Home > Blockchain >  SQL query to get address city change on a date
SQL query to get address city change on a date

Time:02-22

I have a query to find out the address details of an employee

Person_number           country     town/city   start_Date          end_date
--------------------------------------------------------------------------------
10                      CA          Toronto     01-feb-2022         10-feb-2022
10                      CA          Ottawa      11-feb-2022         31-dec-4712

11                      CA          Toronto     10-feb-2022         31-dec-4712

12                      AB          Greenvilee  15-feb-2022         20-feb-2022
12                      AB          Portvilee   21-feb-2022         31-dec-4712

13                      CA          North york  01-feb-2022         09-feb-2022
13                      CA          Waterloo    10-feb-2022         31-dec-4712

I want I want to create a query to get the data only for those employees whose town/city value has changed within the parameter date.

For example: if I pass the parameter date as 01-feb-17-feb 2022, I should get the following output:

Person_number           country     current_town    previous_town   effective_date_ofchange
10                       CA          Toronto            Ottawa          11-feb-2022 
13                       CA          North york         Waterloo        10-feb-2022

person #11 will not come as there is no change within the date. Person#12 will not come as the change is after the parameter date.

Can this be achieved with any analytical function ?

CodePudding user response:

Here's one approach, with the LAG window function:

The fiddle

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';

WITH xdata (person_number, country, town_city, start_date, end_date) AS (
        SELECT 10,  'CA',   'Toronto'   ,  '01-feb-2022', '10-feb-2022' FROM dual UNION
        SELECT 10,  'CA',   'Ottawa'    ,  '11-feb-2022', '31-dec-4712' FROM dual UNION
        SELECT 11,  'CA',   'Toronto'   ,  '10-feb-2022', '31-dec-4712' FROM dual UNION
        SELECT 12,  'AB',   'Greenvilee',  '15-feb-2022', '20-feb-2022' FROM dual UNION
        SELECT 12,  'AB',   'Portvilee' ,  '21-feb-2022', '31-dec-4712' FROM dual UNION
        SELECT 13,  'CA',   'North york',  '01-feb-2022', '09-feb-2022' FROM dual UNION
        SELECT 13,  'CA',   'Waterloo'  ,  '10-feb-2022', '31-dec-4712' FROM dual
     )
   , xtable (person_number, country, town_city, start_date, end_date) AS (
        SELECT person_number, country, town_city
             , to_date(start_date, 'DD-MON-YYYY')
             , to_date(end_date, 'DD-MON-YYYY')
          FROM xdata
     )
   , table2 (person_number, country, current_town, prev_town, start_date) AS (
        SELECT person_number, country, town_city
             , LAG(town_city) OVER (PARTITION BY person_number ORDER BY start_date)
             , start_date
          FROM xtable
     )
SELECT * FROM table2
 WHERE current_town <> prev_town
   AND start_date BETWEEN DATE'2022-02-01' AND DATE'2022-02-17'
;

LAG(x) OVER (PARTITION BY person_number ORDER BY start_date)

This obtains the prior x for each row for the corresponding person, based on the start_date order.

The result:

PERSON_NUMBER COUNTRY CURRENT_TOWN PREV_TOWN START_DATE
10 CA Ottawa Toronto 11-FEB-2022
13 CA Waterloo North york 10-FEB-2022
  • Related