I have the following table
data is accessible here
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=18e9473c82deb4e7e955a0b0cb6f5014
I want to find the employee if he has a city = 'London' and next row after that <> 'London'. After that I should scan the rest rows and catch first row = 'London', if not i should ignore the entire row. the result should be like below
My code and result:
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=cc7863dbe59f80d1058f34a8f7ad0562
Code works if
first city = London
Second city != London
third city = London
But if London instead of coming as a third city let say fourth or fifth it will not works. Code should be:
first city = London
Second city <> London
third city = London if not check next
fourth city = London if not check next
...
to last row for the employee if not find London, skip the entire row.
**
I think LEAD()
with some CASE
logic and IGNORE NULL
s does what you want:
SELECT *
FROM (SELECT t.*,
LEAD(CITY) OVER (PARTITION BY EMP_ID ORDER BY DATETIME) as city_2,
LEAD(datetime) OVER (PARTITION BY EMP_ID ORDER BY DATETIME) as datetime_2,
LEAD(CASE WHEN CITY = 'London' THEN CITY END IGNORE NULLS) OVER (PARTITION BY EMP_ID ORDER BY DATETIME) as city_3,
LEAD(CASE WHEN CITY = 'London' THEN DATETIME END IGNORE NULLS) OVER (PARTITION BY EMP_ID ORDER BY DATETIME) as datetime_3
FROM MY_TABLE t
) t
WHERE CITY = 'London' AND CITY_2 <> 'London' AND CITY_3 = 'London';
Here is a db<>fiddle.
Another option is to use aggregate function
as following:
SELECT T.EMP_ID,
MAX(CASE WHEN MINRN = RANK_CITY THEN CITY END) AS CITY_1,
MAX(CASE WHEN MINRN = RANK_CITY THEN DATETIME END) AS DATE_TIME_1,
MAX(CASE WHEN MINRN + 1 = RANK_CITY THEN CITY END) AS CITY_2,
MAX(CASE WHEN MINRN + 1 = RANK_CITY THEN DATETIME END) AS DATE_TIME_2,
MAX(CASE WHEN CNTCITY = 2 and CITY= 'London' THEN CITY END) AS CITY_3,
MAX(CASE WHEN CNTCITY = 2 and CITY ='London' THEN DATETIME END) AS DATE_TIME_3
FROM (SELECT t.*,
Min(CASE WHEN CITY = 'London' THEN RANK_CITY END) OVER (PARTITION BY EMP_ID) as MINRN,
SUM(CASE WHEN CITY = 'London' THEN 1 END) OVER (PARTITION BY EMP_ID ORDER BY DATETIME) AS CNTCITY,
Max(CASE WHEN CITY = 'London' THEN RANK_CITY END) OVER (PARTITION BY EMP_ID) as MAXRN
FROM MY_TABLE t
) t
WHERE MAXRN - MINRN > 1
GROUP BY EMP_ID
Cheers!!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.