从 Oracle 12 开始,您可以使用MATCH_RECOGNIZE:
SELECT *
FROM table_name
MATCH_RECOGNIZE (
PARTITION BY passenger
ORDER BY "DATE"
MEASURES
FIRST(city) AS city,
COUNT(*) AS count
PATTERN (same_city+)
DEFINE
same_city AS FIRST(city) = city
);
其中,对于样本数据:
CREATE TABLE table_name (PASSENGER, CITY, "DATE") AS
SELECT 43, 'NEW YORK', DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 44, 'CHICAGO', DATE '2021-01-04' FROM DUAL UNION ALL
SELECT 43, 'NEW YORK', DATE '2021-01-02' FROM DUAL UNION ALL
SELECT 43, 'NEW YORK', DATE '2021-01-03' FROM DUAL UNION ALL
SELECT 44, 'ROME', DATE '2021-01-05' FROM DUAL UNION ALL
SELECT 43, 'LONDON', DATE '2021-01-04' FROM DUAL UNION ALL
SELECT 44, 'CHICAGO', DATE '2021-01-06' FROM DUAL UNION ALL
SELECT 44, 'CHICAGO', DATE '2021-01-07' FROM DUAL
输出:
| PASSENGER |
CITY |
COUNT |
| 43 |
NEW YORK |
3 |
| 43 |
LONDON |
1 |
| 44 |
CHICAGO |
1 |
| 44 |
ROME |
1 |
| 44 |
CHICAGO |
2 |
如果你已经对输入结果集进行了排序(注意:表应该被认为是无序的)并且想要保持顺序那么:
SELECT *
FROM (SELECT t.*, ROWNUM AS rn FROM table_name t)
MATCH_RECOGNIZE (
PARTITION BY passenger
ORDER BY RN
MEASURES
FIRST(rn) AS rn,
FIRST("DATE") AS "DATE",
FIRST(city) AS city,
COUNT(*) AS count
PATTERN (same_city+)
DEFINE
same_city AS FIRST(city) = city
)
ORDER BY rn
输出:
| PASSENGER |
RN |
DATE |
CITY |
COUNT |
| 43 |
1 |
01-JAN-21 |
NEW YORK |
3 |
| 44 |
2 |
04-JAN-21 |
CHICAGO |
1 |
| 44 |
5 |
05-JAN-21 |
ROME |
1 |
| 43 |
6 |
04-JAN-21 |
LONDON |
1 |
| 44 |
7 |
06-JAN-21 |
CHICAGO |
2 |
db小提琴here