SQL select multiple counts in the last 12 months including missing months

此生再无相见时 提交于 2020-01-14 02:54:07

问题


I've been trying to create a SQL Query that returns a result that looks something like this:

May     2013    P1  0
May     2013    P2  5
May     2013    P3  2
May     2013    P4  1
June    2013    P1  3
June    2013    P2  2
June    2013    P3  4
June    2013    P4  9
July    2013    P1  0
July    2013    P2  0
July    2013    P3  5
July    2013    P4  2

The idea is I've got two tables Priority and Work:

Priority:
Name|Value
P1    9
P2    7
P3    5
P4    2
...

Work:

ID | PriorityValue | CompleteTime
1    9               03/04/2013
2    5               02/09/2013
3    7               12/01/2014
4    9               11/02/2014

How do I generate count for each priority work over the last 12 months or more?

So far I've looked at the solution from this Include monthly counts including months where data doesn't exist

The query I've got so far is:

;WITH d(d) AS 
(
  SELECT DATEADD(MONTH, n, DATEADD(MONTH, DATEDIFF(MONTH, 0, '20130501'), 0))
  FROM ( SELECT TOP (DATEDIFF(MONTH, '20130501', '20140401') + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) - 1
    FROM sys.all_objects ORDER BY [object_id] ) AS n
)
SELECT 
  d.d,
  DATENAME(MONTH, d.d) as [Month], 
  YEAR(d.d) as [Year], 
  Priority.Name, COUNT(Work.ID) AS Count
FROM d LEFT OUTER JOIN Work
  ON CompleteTime >= d.d
  AND CompleteTime < DATEADD(MONTH, 1, d.d) RIGHT OUTER JOIN Priority on Work.PriorityValue = Priority.Value
GROUP BY d.d, Priority.Name
ORDER BY d.d;

But it only generates a list of months with priority count > 0. For example:

May     2013    P3  5
May     2013    P4  55
July    2013    P3  8
July    2013    P4  48
August  2013    P3  2
August  2013    P4  8

回答1:


The problem is you are grouping by Priority.Name which is null for items that don't exist. To fix you have to give those a name (I used 'P1' below) and then it will work:

SELECT 
  d.d,
  DATENAME(MONTH, d.d) as [Month], 
  YEAR(d.d) as [Year], 
  ISNULL(Priority.Name,'P1'), 
  COUNT(Work.ID) AS Count
FROM d 
LEFT OUTER JOIN Work ON CompleteTime >= d.d AND CompleteTime < DATEADD(MONTH, 1, d.d)
RIGHT OUTER JOIN Priority on Work.PriorityValue = Priority.Value
GROUP BY d.d, ISNULL(Priority.Name,'P1')
ORDER BY d.d;



回答2:


In case anyone looking for a solution, I solved it using CROSS JOIN rather than RIGHT OUTER JOIN as below:

SELECT 
  d.d,
  DATENAME(MONTH, d.d) as [Month], 
  YEAR(d.d) as [Year], 
  ISNULL(Priority.Name,'P1'), 
  COUNT(Work.ID) AS Count
FROM d 
LEFT OUTER JOIN Work ON CompleteTime >= d.d AND CompleteTime < DATEADD(MONTH, 1, d.d)
CROSS JOIN Priority on Work.PriorityValue = Priority.Value
GROUP BY d.d, ISNULL(Priority.Name,'P1')
ORDER BY d.d;


来源:https://stackoverflow.com/questions/25205285/sql-select-multiple-counts-in-the-last-12-months-including-missing-months

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!