问题
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