【问题标题】:Datediff SQL-server query for statistical data with count & group byDatediff SQL-server 查询统计数据的计数和分组依据
【发布时间】:2014-05-23 09:08:08
【问题描述】:

所以我想要实现的是统计有多少用户触发了 EventCode 90,相对于他们上次收到通知的时间。

源表如下:

ServiceOne

UserNr         RegisteredUntil            NotificationMonth
532091985      2016-05-15 00:00:00.000    5
950628185      2016-03-15 00:00:00.000    3
561007126      2016-09-15 00:00:00.000    9

通知

UserNr         NotificationNr     NotificationDate            Service
532091985      134567             2013-04-16 00:00:00.000     1
532091985      153468             2014-04-15 00:00:00.000     1
950628185      235481             2014-02-17 00:00:00.000     1
561007126      354812             2012-08-15 00:00:00.000     1

事件日志

Time                        EventCode      UserNr
2012-12-19 00:00:00.000     90             561007126
2014-05-02 00:00:00.000     90             120456873
2009-08-24 00:00:00.000     90             935187423

我想要的表是这样的:

CancMonth CancAmount
0         49091
1         53564
2         14308

到目前为止我所拥有的是

Select Max(datediff(month, I.NotificationDate, E.Time)  ) as CancMonth
,Count(datediff(month, I.NotificationDate, E.Time)  ) as CancAmount

From ServiceOne P, Eventlog E, Notifications N
Where P.UserNr=E.UserNr
AND P.UserNr=N.UserNr
AND E.EventCode = 90 --EventCode 90 is both flagging for deregistration and manual deregistration
AND N.Service=1
AND P.Status In (0,4) -- 0 is not registered and 4 is flagged for deregistration
AND datediff(month, N.NotificationDate, E.Time ) < 13 --Notifications are sent once a year
AND N.NotificationDate < E.Time

Group By datediff(month, N.NotificationDate, E.Time )
Order By CancMonth

我计算了这提供了多少条记录,它返回的记录比我在 ServiceOne 中的被动和标记用户多出大约 35000 条。

非常感谢您的帮助,因为这让我在过去的几天里头疼不已。

编辑:我添加了我的源表和所有可能可用的列以及一些随机样本数据

【问题讨论】:

  • 我确实发布了一个建议使用连接的答案,但我删除了它,因为它看起来很明显。你试过加入吗?您有时间创建一个 sqlfiddle 以便我们可以查看表结构和示例数据
  • 我确实看到了您的答案,并在我的问题中添加了一些示例数据。不幸的是,左连接是不可能的。您建议的那个已经工作了 23 分钟,但仍未完成。至于 sqlfiddle,我不完全确定那是什么
  • 这些表有索引吗?您现有的代码使用内部联接,但如果您的逻辑需要,您可能需要使用外部联接。
  • 我对所有表都有索引。很抱歉像我一样缺乏经验,但是外部联接与内部联接的区别是什么?无论如何,下面的 Jithin 给出了一个很好的答案,解决了我的问题。

标签: sql-server join datediff


【解决方案1】:

这是你要找的吗?

--I assue that Latest NotificationDate has Largest NotificationNr

SELECT      MAX(DATEDIFF(MONTH, I.NotificationDate, E.Time)) AS CancMonth,
            COUNT(DATEDIFF(MONTH, I.NotificationDate, E.Time)) AS CancAmount
FROM        ServiceOne P 
JOIN        Eventlog E ON P.UserNr  =E.UserNr 
JOIN        (
            SELECT  N.*
            FROM    Notifications N
            JOIN    (
            SELECT  UserNr,
                    MAX(NotificationDate) NotificationDate,
                    MAX(NotificationNr) NotificationNr        
            FROM    Notifications) LU 
    ON      N.UserNr = LU.UserNr 
    AND     N.NotificationDate = LU.NotificationDate 
    AND     N.NotificationNr = LU.NotificationNr
            ) N ON P.UserNr = N.UserNr 
WHERE       E.EventCode = 90 
AND         N.Service=1
AND         P.Status In (0,4)
AND         DATEDIFF(MONTH, N.NotificationDate, E.Time ) < 13
AND         N.NotificationDate < E.Time
GROUP BY    DATEDIFF(MONTH, N.NotificationDate, E.Time )
ORDER BY    CancMonth

【讨论】:

  • 这正是我要找的,谢谢你的帮助!在一个小的旁注中,这个查询怎么会这么快呢?它是巨大的嵌套连接,它将具有数十万条记录的表拉在一起。然而它在5秒内完成。有趣。
  • 如果 NotificationDate 和 NotificationNr 并行递增,你只需要单独取 MAX(NotificationNr) ..
  • 我确实注意到了这一点,并冒昧地从查询中完全删除了 NotificationNr,因为我真正需要的 Notifications 只是 Date 和 UserNr 来配对
  • 关于您的代码,我也忘了提及一件事。要使其工作,您需要在 LU Select 子查询中添加 Group by CustomerNr
猜你喜欢
  • 1970-01-01
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 2013-07-12
相关资源
最近更新 更多