从每月的开始和结束日期中获得不同的任务计数

时间:2018-07-25 07:07:05

标签: sql sql-server tsql

我想制作一个瀑布图(在报表应用程序中),以根据任务的“打开时”和“时间戳记”显示任务的添加和分辨率。

我在MSSQL Server 2016上有一个包含“任务”表的数据库:

SELECT [SysID], [Opened At], [Resolved At]
FROM task
ORDER BY [Opened At] ASC;

SysID                               Opened At               Resolved At
9086c6254f3d578070a1afee0310c79a    2018-04-30 23:53:25.000 2018-05-01 00:57:46.000
7c86c6254f3d578070a1afee0310c7c8    2018-04-30 23:53:27.000 2018-05-01 01:05:22.000
9d8606254f3d578070a1afee0310c7a9    2018-04-30 23:53:29.000 2018-05-01 01:05:42.000
f986c6254f3d578070a1afee0310c783    2018-04-30 23:53:31.000 2018-05-01 01:14:22.000
45c312e94ffd5780a35d87501310c775    2018-05-01 00:51:22.000 2018-05-01 04:11:48.000

如果任务具有“打开时间”时间戳记而没有“已解决的时间”时间戳记,则该任务被视为“活动”。任务在打开的当天并不一定总是标记为已解决,所以我想看看每天结束时还有多少剩余。

我想结束这个SQL结果,该结果显示每天结束时活动票证的差异:

Date Created    Opened Count    Closed Count    Difference
27/10/2017      17              5               12
28/10/2017      11              13              -2
29/10/2017      10              9               1
30/10/2017      17              12              5
31/10/2017      17              20              -3
1/11/2017       23              19              4
2/11/2017       19              25              -6
3/11/2017       13              30              -17

我当前的查询是

SELECT * FROM (
     SELECT
      CONVERT(VARCHAR(10), task.[Opened At], 126) AS [Date Opened],
      SUM(CASE WHEN [Opened At] IS NOT NULL THEN 1 ELSE 0 END) AS [Opened Count]
      FROM task GROUP BY CONVERT(VARCHAR(10), task.[Opened At], 126) 

      UNION ALL
      SELECT CONVERT(VARCHAR(10), task.[Resolved At], 126) AS [Date Resolved],
      SUM(CASE WHEN [Resolved At] IS NOT NULL THEN 1 ELSE 0 END) AS [Resolved Count]
      FROM task GROUP BY CONVERT(VARCHAR(10), task.[Resolved At], 126)
) t

但是,它只返回“打开日期”和“打开计数”列。 “打开的计数”列中的数据不正确。如果我只选择不带UNION的Opened At或Closed At,则查询工作正常。区别应该只是关闭计数-打开计数。

由于需要先打开票证才能解决票证,所以我想根据“打开日期”列为基础日期。

我看了很多描述上面使用的子查询技术的文章,但是我不知道为什么它不返回另一列。我已经研究了COUNT(*)OVER(ORDER BY ...),但是我所看到的所有示例都是针对每行有不同事件的表。 (带有借方和贷方的银行帐户是常见的帐户,与这种结构不匹配,更多的是对行进行更新以更改查询的计数)。

有人可以帮我吗?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您正在寻找孤立的日子:

  • 当天打开了多少个任务
  • 当天完成了多少任务

您不会对一天结束时实际上有多少个任务感兴趣(我们必须将当天或之前打开的所有未解决的任务相加)。

因此,这仅仅是每天打开的任务与每天解决的任务的完整外部连接:

select
  coalesce(opened.dt, closed.dt) as day,
  coalesce(opened.cnt, 0) as opened_count,
  coalesce(resolved.cnt, 0) as resolved_count,
  coalesce(opened.cnt, 0) - coalesce(resolved.cnt, 0) as diff
from
(
  select convert(date, [Opened At]) as dt, count(*) as cnt
  from task
  group by convert(date, [Opened At])
) opened
full outer join
(
  select convert(date, [Resolved At]) as dt, count(*) as cnt
  from task
  group by convert(date, [Resolved At])
) resolved on resolved.dt = opened.dt
order by day;

答案 1 :(得分:1)

您只需要group by日期即可。在脚本中进行简单的修改即可解决问题

SELECT [Date Created]
    ,sum([Opened Count]) [Opened Count]
    ,sum([Resolved Count]) [Resolved Count]
    ,sum([Resolved Count]) - sum([Opened Count]) DifferenceCount
FROM (
    SELECT CONVERT(VARCHAR(10), task.[Opened At], 126) AS [Date Created]
        ,count(*) AS [Opened Count]
        ,0 [Resolved Count]
    FROM task
    GROUP BY CONVERT(VARCHAR(10), task.[Opened At], 126)

    UNION ALL

    SELECT CONVERT(VARCHAR(10), task.[Resolved At], 126) AS [Date Created]
        ,0 [Opened Count]
        ,count(*) AS [Opened Count] AS [Resolved Count]
    FROM task
    GROUP BY CONVERT(VARCHAR(10), task.[Resolved At], 126)
    ) t
GROUP BY [Date Created]

答案 2 :(得分:0)

我想在打开和解决之间进行完全连接。

但要多加修饰。
为当天打开并解决的问题添加总计。

因为,如果您真的想知道在打开的同一天解决了多少? 然后,仅比较期末和期末总计会产生误导。

例如,如果您只有图钉([打开位置],[已解决位置]):
('2018-01-01','2018-01-02'),('2018-01-02','2018-01-01')

然后在“创建时间”两天,TotalOpened = 1和TotalClosed = 1,且Diff = 0
由于Diff = 0,因此可以假设第二天没有任何问题得到解决。
但实际上,这两个塔普尔都没有在同一天打开和关闭。

示例片段:

declare @task table (id int identity(1,1), [Opened At] datetime, [Resolved At] datetime);

insert into @task ([Opened At], [Resolved At]) values
 (GetDate()-1.1, GetDate()-1)
,(GetDate()-2, GetDate()-1)
,(GetDate()-3, GetDate()-2)
,(GetDate()-5, GetDate()-4)
;

select 
coalesce([OpenedDate],[ClosedDate]) as [Created At], 
isnull(TotalOpened,0) as [Opened Count], 
isnull(TotalClosed,0) as [Closed Count],
isnull(TotalOpened,0) - isnull(TotalClosed,0) as [Difference],
isnull(TotalSameDayClosure,0) as [SameDayClosure Count] 
from 
(
    select 
     convert(date,[Opened At]) as [OpenedDate], 
     count(*) as TotalOpened,
     count(case when [Resolved At] is not null and convert(date,[Opened At]) = convert(date,[Resolved At]) then 1 end) as TotalSameDayClosure
    from @task
    group by convert(date,[Opened At])
) Opened
full join
(
    select convert(date,[Resolved At]) as [ClosedDate], count(*) as TotalClosed
    from @task
    group by convert(date,[Resolved At])
) Closed
on Opened.[OpenedDate] = Closed.[ClosedDate];
相关问题