查询构造:Count,Case,Datediff和Group By

时间:2013-09-09 15:51:59

标签: sql sql-server tsql datetime

[重新设计先前的问题,这是一个关于游标的问题。]

我正在寻找一种在特定日期条件下选择计数的方法。

假设有一个表T1,包含2个字段(IDDate)。 ID不是唯一键。该表通过id记录事件,并且一些id经常发生,一些不经常发生。

例如:

ID  |  Date
1   |  2010-01-01
2   |  2010-02-01
3   |  2010-02-15
2   |  2010-02-15
4   |  2010-03-01

我想创建一个包含以下字段的新表:ID,日期,ID在日期之前的6个月内出现的次数,ID在Date之后的6个月内出现的次数。

实质上,对于现有表中的每一行,我想添加一个列,以回顾过去六个月中出现的相同ID的时间,并预测在接下来的六个月内出现相同ID的时间。

因此,该示例的输出有望看起来像:

ID  |  Date        | Lookback  |  Lookahead
1   |  2010-01-01  | 0         |  0
2   |  2010-02-01  | 0         |  1
3   |  2010-02-15  | 0         |  0
2   |  2010-02-15  | 1         |  0
4   |  2010-03-01  | 0         |  0

是否有最佳方法来制定适当的查询?

1 个答案:

答案 0 :(得分:3)

您可以使用自联接(假设您有KeyID的主键)执行此操作:

SELECT  T.ID,
        T.Date,
        Lookback = COUNT(CASE WHEN t2.Date < T.Date THEN t2.ID END),
        Lookahead = COUNT(CASE WHEN t2.Date > T.Date THEN t2.ID END)
FROM    T
        INNER JOIN T t2
            ON t2.ID = t.ID
            AND t2.Date >= DATEADD(MONTH, -6, T.Date)
            AND T2.Date < DATEADD(MONTH, 6, T.Date)
GROUP BY T.ID, T.Date, T.KeyID;

<强> Example on SQL Fiddle

关键是它只是加入前6个月和接下来6个月的所有行,并计算结果。 COUNT(CASE WHEN...确保对于before列,您只计算之前的记录,以及之后的记录。