按月/年创建和关闭的记录数

Posted

技术标签:

【中文标题】按月/年创建和关闭的记录数【英文标题】:Count of records created and closed by month/yy 【发布时间】:2019-08-07 22:13:21 【问题描述】:

尝试提取动态列表(并推送到可视化应用程序),该列表显示每月创建了多少支持票证以及关闭了多少票。需要 3 列 - 创建的案例数、关闭的案例数和 YYYYMM。创建/关闭日期都是日期时间字段。不能在同一行同时创建和关闭。

SELECT
COUNT (t1.id) AS Tickets_Created
,CAST(DATEPART(yy,t1.CreatedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),t1.CreatedAt,112),5,2)) AS YYYYMM
FROM [Ticket] AS T1
WHERE T1.Spam=0
GROUP BY CAST(DATEPART(yy,t1.CreatedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),t1.CreatedAt,112),5,2))
--ORDER BY YYYYMM

UNION

SELECT

COUNT (t.id) AS Tickets_Resolved
,CAST(DATEPART(yy,S.ResolvedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),S.ResolvedAt,112),5,2)) AS YYYYMM
FROM [Ticket] T
LEFT JOIN FS.TicketStatus S ON S.TicketNK=T.id
WHERE T.Spam=0 AND YEAR(s.ResolvedAt) > '2016'
GROUP BY CAST(DATEPART(yy,S.ResolvedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),S.ResolvedAt,112),5,2))

预期结果:

YYYYMM    Created Closed
2017 11   50      30
2017 12   45      23
2018 01   90      56

实际结果(关闭日期显示在下一行):

Tickets_Created YYYYMM
   1           2017 11
   2           2017 11
   16          2017 12
   25          2017 12
   34          2018 01
   54          2018 01

【问题讨论】:

欢迎来到 SO。请注明您使用的数据库。 对于一个更有可能得到好答案的好问题,将表结构包括为CREATE TABLE 语句,示例数据为INSERT INTO 语句,使用该示例数据的所需结果,您的当前尝试(您已经包含该尝试)并标记您正在使用的 DBMS 和版本。您可以随时edit 一个问题,通过添加此类信息来提高其质量。 提示:在 SQL 中将日期转换为字符串/文本/nvarchar 是一种代码味道,因为通常您不需要这样做。与使用字符串转换相比,有很多更好的方法可以将日期分组为月份和年份。 【参考方案1】:

您的行合并,因为您使用 UNION,您需要加入才能获得所需的输出

SELECT t1.YYYYMM, t1.Tickets_Created, t2.Tickets_Closed
FROM 
    (SELECT COUNT (t1.id) AS Tickets_Created
      ,CAST(DATEPART(yy,t1.CreatedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),t1.CreatedAt,112),5,2)) AS YYYYMM
    FROM [Ticket] AS T1
    WHERE T1.Spam=0
    GROUP BY CAST(DATEPART(yy,t1.CreatedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),t1.CreatedAt,112),5,2))) as t1
LEFT JOIN
    (SELECT COUNT (t.id) AS Tickets_Resolved
        ,CAST(DATEPART(yy,S.ResolvedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),S.ResolvedAt,112),5,2)) AS YYYYMM
    FROM [Ticket] T
    LEFT JOIN FS.TicketStatus S ON S.TicketNK=T.id
    WHERE T.Spam=0 AND YEAR(s.ResolvedAt) > '2016'
    GROUP BY CAST(DATEPART(yy,S.ResolvedAt) AS VARCHAR) +' '+ (SUBSTRING(CONVERT(NVARCHAR(6),S.ResolvedAt,112),5,2))) as t2 on t2.YYYYMM = t1.YYYYMM

【讨论】:

非常感谢!!!无法弄清楚使用相同字段时要加入这些内容。 如果有一个月没有创建任何票证,这将不起作用。【参考方案2】:

这是基本方法。我会让你把剩下的过滤器放回去:

WITH data as (
    SELECT
        1 as tag,
        DATEPART(yy, CreatedAt) as yy,
        DATEPART(mm, CreatedAt) as mm
    FROM Ticket
    UNION ALL
    SELECT
        2 as tag,
        DATEPART(yy, ResolvedAt) as yy,
        DATEPART(mm, ResolvedAt) as mm
    FROM Ticket
)
SELECT yy, mm,
    COUNT(CASE WHEN tag = 1 THEN 1 END) as Created,
    COUNT(CASE WHEN tag = 2 THEN 1 END) as Resolved
FROM data
GROUP BY yy, mm;

【讨论】:

非常优雅,谢谢 - 需要学习,感谢您的帮助!!

以上是关于按月/年创建和关闭的记录数的主要内容,如果未能解决你的问题,请参考以下文章

LINQ:在日期时间字段中按月和年分组

删除数百万条记录 oracle [关闭]

如何在bigquery中按月/年汇总

linux 命令点滴记录(centos)

mysql如何更快地插入数百万条记录? [关闭]

将 SQL 查询转换为 PL/SQL 可以提高 Oracle 12c 中的性能吗? [关闭]