SQL跟踪每周发布一次(递归函数?)

时间:2014-09-15 18:27:07

标签: sql sql-server-2008-r2 recursive-query

我已尽最大努力寻找但无法找到答案。我有一个表,每周我记录另一个表中的ID;这样我就可以通过ID跟踪问题了。因此,如果每周出现一个ID,问题就在那里。如果下一周ID不再存在,则问题得以解决。

例如,这将是一个示例数据集:

创建表#recursiveTest
(ID int,
 快照日期
 )
插入#recursiveTest
价值
(123456,' 2014年9月1日&#39),
(123456,' 2014年9月8日&#39),
(123456,' 2014年9月15日&#39),
(3123456,' 2014年9月8日&#39),
(3123456,' 2014年9月15日&#39),
(3123456,' 2014年9月22日&#39),
(6123456,' 2014年9月29日')

我想要的观点是:
在9/1,我有一个问题(只有一个ID,日期9/01)
9月8日,我有2个问题,其中一个是新的(3123456),因为上周没有问题 在9月15日,我还有2个问题 在9月22日,我有1个已解决的问题(123456,已不再存在),仍有一个问题 在9月29日,我有另一个已解决的问题,加上之前没有的新问题(6123456)

我能够(我认为)在伪代码中陈述我想要的内容,但不能将其翻译成SQL代码......我正在使用MS SQL server 2008.

的伪代码:
对于每个快照日期的每个ID:
  如果没有先前的快照日期,请将问题标记为新的   否则:
     上周离开加入;如果上周ID为空,那么它是一个新问题      上周正确加入;如果本周ID为空,那么它已经解决了

我觉得我需要某种递归函数来逐周进行并进行连接,然后进行操作以查明是否存在新问题或已解决的问题,但我无法找到方法。

任何可以提供帮助的巫师?我非常感激。

非常感谢你的时间。

1 个答案:

答案 0 :(得分:0)

也许这就是你之后的...... 用简单的英语。

我认为您希望显示所有ID和日期,但是在新的那一天指出哪些是新的,哪些在它们被解决的那天关闭。我看到的问题是,由于下周数据可能尚未可用,因此已解决可能会返回误报,因此将为空。因此,当一个人不在时,联合和缺失数据似乎都得到了解决。

SELECT Case when RT2.SnapshotDate is null then 1 else 0 end as isNew, 
 case when RT3.snapshotDate is null then 1 else 0 end as isResolved,
 RT1.ID , RT1.SnapshotDate
FROM  recursiveTest RT1
LEFT JOIN recursiveTest Rt2
  on RT1.ID = RT2.ID 
 and RT1.Snapshotdate > Rt2.snapshotdate
LEFT JOIN RecursiveTest RT3
 on RT1.ID = RT3.ID
 and RT1.SnapshotDate < RT3.SnapshotDate
GROUP BY Case when RT2.SnapshotDate is null then 1 else 0 end, 
         case when RT3.snapshotDate is null then 1 else 0 end, RT1.ID , RT1.SnapshotDate
ORDER BY RT1.ID, Rt1.SnapshotDate

返回:

isNew isResolved ID       SnapShotDate
    1   0        123456   01-SEP-14 00:00:00
    0   0        123456   08-SEP-14 00:00:00
    0   1        123456   15-SEP-14 00:00:00
    1   0        3123456  08-SEP-14 00:00:00
    0   0        3123456  15-SEP-14 00:00:00
    0   1        3123456  22-SEP-14 00:00:00
    1   1        6123456  29-SEP-14 00:00:00

由于我们并不关心之前有多少人或之后有多少人,所以我使用分组来限制可能在给定条目上发生的可能的卡地亚。

我在顶部显示的问题在ID-3343456的29-SEP-14上可见。下周不可见,因此它被标记为已解决。但事实并非如此。您提供的数据无法指示此情况,除非我们假设最大日期始终保持打开状态,无论数据集如何。如果是这样,我们可以通过...来管理这个......

Select isNew, isResolved, ID, Snapshotdate FROM (
Select Case when RT2.SnapshotDate is null then 1 else 0 end as isNew, 
 case when RT1.snapshotDate = (Select max(snapshotDate) from recursiveTest) then 0 
       when RT3.snapshotDate is null then 1  else 0 end as isResolved,
 RT1.ID , RT1.SnapshotDate
from recursiveTest RT1
LEFT JOIN recursiveTest Rt2
  on RT1.ID = RT2.ID 
 and RT1.Snapshotdate > Rt2.snapshotdate
LEFT JOIN RecursiveTest RT3
 on RT1.ID = RT3.ID
 and RT1.SnapshotDate < RT3.SnapshotDate) 
GROUP BY isNew, isResolved, ID, Snapshotdate
order by ID, SnapshotDate

这给了我们:

  isNew isResolved ID       SnapShotDate
    1   0          123456   01-SEP-14 00:00:00
    0   0          123456   08-SEP-14 00:00:00
    0   1          123456   15-SEP-14 00:00:00
    1   0          3123456  08-SEP-14 00:00:00
    0   0          3123456  15-SEP-14 00:00:00
    0   1          3123456  22-SEP-14 00:00:00
    1   0          6123456  29-SEP-14 00:00:00

或作为CTE(公用表表达式)产生相同的结果

WITH CTE AS (
SELECT Case when RT2.SnapshotDate is null then 1 else 0 end as isNew, 
 case when RT1.snapshotDate = (Select max(snapshotDate) from recursiveTest) then 0 
       when RT3.snapshotDate is null then 1  else 0 end as isResolved,
 RT1.ID , RT1.SnapshotDate
FROM recursiveTest RT1
LEFT JOIN recursiveTest Rt2
  on RT1.ID = RT2.ID 
 and RT1.Snapshotdate > Rt2.snapshotdate
LEFT JOIN RecursiveTest RT3
 on RT1.ID = RT3.ID
 and RT1.SnapshotDate < RT3.SnapshotDate) 
SELECT isNew, isResolved, ID, SnapshotDate
FROM CTE
GROUP BY isNew, isResolved, ID, Snapshotdate
ORDER BY ID, SnapshotDate