【问题标题】:Look back further than one record lag回顾超过一个记录滞后
【发布时间】:2016-03-29 11:52:44
【问题描述】:

我有一张表格,可以跟踪位置中的物品。由于该表由两个独立的系统提供,因此日期可能重叠。让我们称它们为 System1 和 System2。

我正在使用分区来检查日期何时重叠,但是当出现错误的记录不是相邻行时遇到了问题。即来自 System2 的第一条记录存在于来自 System1 的记录中,因此被丢弃,但是 System2 中的第二条记录要么在 System2 中的最后一条记录结束之前开始,要么同样在最后一条记录中。

为了解决这个问题,我试图捕获 System1 中的最后一个结束日期,这样我就可以轻松地根据这个值检查我的日期。我的问题是我对分区知之甚少,无法做到这一点。我本质上需要一个分区而不是一个分区。主分区基于 PartID,第二个分区基于 SysID,或者您甚至可以使用我猜的 Source。为了使事情变得整洁,我在下面的示例数据中将唯一记录 ID 重命名为单个数字 ID。

当前代码只是 ADTM 排序的 PartID 上的一系列 LEAD/LAG 语句分区

样本数据: 对于这些数据,我目前正确地将带有单个 * 的记录识别为错误。然而,带有 ** 的错误是一个无法识别的错误,因为它包含在 System1 的记录 3757871 中。我需要能够将 ID 6 的日期与 ID 4 的日期进行比较,以便识别该故障。

Source        SysID     PartID   ID       ADTM                SDTM
System1     A8871247    1661181  1   2014-08-15 11:21   2014-08-15 11:35
*System2    1661181     1661181  2   2014-08-15 11:27   2014-08-19 11:04*
System1     A8871247    1661181  3   2014-08-15 11:35   2014-08-16 22:43
System1     A8871247    1661181  4   2014-08-16 22:43   2014-08-20 15:44
*System2    1661181     1661181  5   2014-08-19 11:04   2014-08-19 11:05*
**System2   1661181     1661181  6   2014-08-19 11:05   2014-08-20 15:30**
System2     1661181     1661181  7   2014-08-20 15:30   2014-08-20 15:44
System2     1661181     1661181  8   2014-08-20 15:44   2014-08-22 11:34

我的最终结果是 ID 2、5、6,7 将被丢弃,ID 8 将其 ADTM 更新为 ID 4 的 SDTM,以创建系统之间的无缝过渡。

基本上我需要的是MAX(SDTM) OVER(PARTITION BY PartID ORDER BY ADTM WHERE Source = 'System1')

【问题讨论】:

  • 我想确保我理解完整的目标,为什么 ID 7 不是错误? - 它的时间在 ID 4 的时间之内。
  • 哎呀,你是对的。这也是一个错误。
  • 好的,谢谢,我还有一个问题:如果您有部分重叠(假设 ID 9 的 ADTM = 2014-08-22 11:30 和 SDTM = 2014-08-23 11:50)会这被认为是一个错误,或者您会将 SDTM 更新为先前非错误的最大 ADTM(根据示例,2014-08-22 11:34)。
  • 不,那很好。一个更进一步的过程将更新 ID 9 的 ADTM 并将其设为 11:34。

标签: sql sql-server tsql sql-server-2012 window-functions


【解决方案1】:

编辑:我绝对不知道您要做什么,但根据您的实际问题,您可以使用以下方法获得所有先前行的最大 SDTM:

with t2 as (
    select *, max(SDTM) over (partition by PartID order by ADTM, ID) maxSDTM
    from table_name
)
select *, lag(maxSDTM, 1) over (partition by PartID order by ADTM, ID)
from t2

通过在 MAX 中使用 over 子句,您可以使其成为一个窗口函数并获得包括当前行在内的所有先前行的最高 SDTM。然后你需要基本上排除当前行,这样你就可以使用 LAG 来获得前一个最大值。希望这会有所帮助,对不起,我不明白你的最终目标。

老:我可能不理解这个问题,但如果是这样,我的直觉会改为使用自联接。以下查询应识别所有错误:

SELECT *
FROM table_name t
JOIN table_name prev
ON (t.ADTM > prev.ADTM OR (t.ADTM = prev.ADTM AND t.ID > prev.ID))
    AND t.SDTM <= prev.SDTM
    AND t.PartID = prev.PartID

【讨论】:

  • 这似乎不起作用。我真正追求的只是一种通过 PartID 捕获分区中 system1 的最大 sdtm 的方法
  • 您想要每个零件 ID 的最大 SDTM?那将是按操作分组。或者您是否希望在当前行之前按部件 ID 分区的每行最大 SDTM?
猜你喜欢
  • 2017-04-14
  • 2022-12-13
  • 2014-02-11
  • 2017-12-23
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多