【问题标题】:Query Construction: Count, Case, Datediff, and Group By查询构造:Count、Case、Datediff 和 Group By
【发布时间】:2013-09-09 15:51:59
【问题描述】:

[重新构建先前的问题,该问题被提出为关于光标的问题。]

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

假设有一个表 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 出现在日期后 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

有没有最好的方法来制定适当的查询?

【问题讨论】:

  • 您能否根据您发布的示例数据修改您的问题以包含预期输出?
  • 什么查询?你没有描述查询,你描述了一个table?请澄清您的问题。
  • Basic Cursor in MS SQL Server 的可能重复项

标签: sql sql-server tsql datetime


【解决方案1】:

您可以通过自联接来做到这一点(假设您有一个 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 列,您只计算之前的记录,而之后只计算之后的记录。

【讨论】:

  • 您好,谢谢您,您能解释一下为什么join中的行数比原始表中的少吗?是不是因为表在 ID 和 Date 上不是唯一的?
  • 不应该,在我发布的示例中,它是相同的数字 (5)。
  • 我不确定它是否有效。它从 18,000 行减少到 11,000 行。
  • 对不起,是的,你是对的,这是因为 (ID, Date) 不是彼此唯一的。你的桌子上有主键吗?如果是这样,请将其添加到GROUP BY,您应该可以解决删除行的问题。
  • 我可以做一个。如果主键是 Key_ID,我将如何更改查询?
猜你喜欢
  • 2021-12-22
  • 2021-12-19
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多