带窗口功能的时间戳之间的最小差异

时间:2019-02-11 06:24:13

标签: sql-server-2014 window-functions

我有以下基本数据集。

我想知道每个ProcessStepOne记录的ProcessStepLast时间戳。

  • 每个PersonId的最新ProcessStepOne记录应具有相同PersonId的最新ProcessStepLast记录。
  • 下一个最新的ProcessStepOne记录应该具有下一个最新的ProcessStepLast记录,依此类推。
  • ProcessStepLast记录只能属于一个ProcessStepOne记录。
  • 每个PersonId始终至少有一个ProcessStepOne。
  • 每个PersonId可能有零个,一个或多个ProcessStepLast记录。

如果可能的话,我宁愿不加入时间戳,并想知道这是否适合使用窗口函数?我已经试过了,但是不能完全到达那儿。

任何帮助将不胜感激。

Id       PersonId    ProcessStepOne
1084465  11802   2019-01-18 15:45:44.000
1084507  11802   2019-01-18 16:07:22.000

Id       PersonId    ProcessStepLast
1016970  11802   2019-01-24 12:51:52.600
1016996  11802   2019-01-24 12:55:21.953
1013472  11802   2019-01-24 12:51:45.803 

Id       PersonId    ProcessStepOne            ProcessStepLast
1084465  11802   2019-01-18 15:45:44.000   2019-01-24 12:51:52.600
1084507  11802   2019-01-18 16:07:22.000   2019-01-24 12:55:21.953

1 个答案:

答案 0 :(得分:0)

您的预期输出似乎并不完全符合您的描述,因为第二个数据集中的2019-01-24 12:51:45.803记录没有出现在任何地方。但是,这里可行的一般解决方案是将两个表合并在一起,然后成对聚合:

WITH cte AS (
    SELECT Id, PersonId, ProcessStepOne AS ProcessStep, 1 AS source,
        ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY ProcessStepOne) rn
    FROM table1
    UNION ALL
    SELECT Id, PersonId, ProcessStepTwo, 2,
        ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY ProcessStepTwo)
    FROM table2
)

SELECT
    MAX(CASE WHEN source = 1 THEN Id END) AS Id,
    PersonId,
    MIN(ProcessStep) AS ProcessStepOne,
    MAX(ProcessStep) AS ProcessStepTwo
FROM cte
GROUP BY
    PersonId,
    rn;

enter image description here

Demo

作为旁注,我在联合查询CTE中引入的计算列source在那里,因此我们可以记住哪个Id值对应于第一个表。这是为了满足您在预期输出中使用第一个来源Id标签的要求。