SQL , 分析函数 , rownumber

SQL , Analytical Functions , rownumber

我需要在 SQL 中获取相同的行号或数值来对符合条件的值进行分组,如下例所示:

如果我们有相同的 Agent 名称,并且在按名称应用分区并按时间排序后,当前行和前一行值之间的时间差异小于 06:00 小时 然后添加相同的行号,否则增加它。

行数据和行号输出示例:

person  date_time   rownumber
A   01/04/2018 10:00    1
A   01/04/2018 13:00    1
A   01/04/2018 14:00    1
A   01/04/2018 15:00    1
A   01/04/2018 23:00    2
A   02/04/2018 03:00    2
A   02/04/2018 12:00    3
A   02/04/2018 16:00    3
B   01/04/2018 17:00    4
B   01/04/2018 20:30    4
C   01/04/2018 18:00    5
C   01/04/2018 22:00    5

您可以结合使用 LAG 和 SUM 分析函数来执行此操作,如下所示:

WITH your_table AS (SELECT 'A' person, to_date('01/04/2018 10', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('01/04/2018 13', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('01/04/2018 14', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('01/04/2018 15', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('01/04/2018 23', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('02/04/2018 03', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('02/04/2018 12', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'A' person, to_date('02/04/2018 16', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'B' person, to_date('01/04/2018 17', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'B' person, to_date('01/04/2018 20', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'C' person, to_date('01/04/2018 18', 'dd/mm/yyyy hh24') date_time FROM dual UNION ALL
                    SELECT 'C' person, to_date('01/04/2018 22', 'dd/mm/yyyy hh24') date_time FROM dual)
SELECT person,
       date_time,
       SUM(period_change) OVER (ORDER BY person, date_time) rownumber
FROM   (SELECT person,
               date_time,
               CASE WHEN date_time - LAG(date_time, 1, date_time - 7/24) OVER (PARTITION BY person ORDER BY date_time) > 6/24 THEN 1 ELSE 0 END period_change
        FROM   your_table);

PERSON DATE_TIME    ROWNUMBER
------ ----------- ----------
A      01/04/2018           1
A      01/04/2018           1
A      01/04/2018           1
A      01/04/2018           1
A      01/04/2018           2
A      02/04/2018           2
A      02/04/2018           3
A      02/04/2018           3
B      01/04/2018           4
B      01/04/2018           4
C      01/04/2018           5
C      01/04/2018           5

每当触发新组时,都会在附加列中添加 1。

一旦你有了它,你就可以对该列进行 运行 求和。这意味着在每次组更改后,后续行将分配相同的编号,直到下一次组更改。

N.B。正如 Peter Lang 在下面的评论中所建议的那样,您可能更愿意将生成 "period_change" 列的 case 语句更改为:

CASE WHEN date_time - LAG(date_time) OVER (PARTITION BY person ORDER BY date_time) < 6/24 THEN 0 ELSE 1 END