j0nnyf1ve j0nnyf1ve - 5 months ago 14
SQL Question

SQL Query that Groups Multiple Date Fields

I have a table that has several date fields. For example, in the defects table, I have the following: dateAssigned, dateCompleted, dateResolved. I am trying to get a query that summarizes the defects as such:

| Number Assigned | Number Completed | Number Resolved
-----------------------------+------------------+-----------------
Mar-2011 | 33 | 22 | 33
Apr-2011 | 10 | 11 | 22
May-2011 | 22 | 66 | 46


etc

I have come up with the following to no avail:

SELECT year(d.dateAssigned)
,month(d.dateAssigned)
,COUNT(d.dateAssigned)
,COUNT(d.dateCompleted)
,COUNT(d.dateResolved)
FROM defect d
GROUP BY year(d.dateAssigned), month(d.dateAssigned)
ORDER BY year(d.dateAssigned), month(d.dateAssigned)


This works correctly for summarizing the dateAssigned defects, but not for the others. I realize this is probably due to the fact I am grouping by dateAssigned, but I dont know how else to do it.

Any help would be appreciated.

Answer

This is one way to do it.

SELECT YEAR(typedate), 
       MONTH(typedate), 
       SUM(CASE 
             WHEN TYPE = 'assinged' THEN 1 
             ELSE 0 
           END) number_assigned, 
       SUM(CASE 
             WHEN TYPE = 'completed' THEN 1 
             ELSE 0 
           END) number_completed, 
       SUM(CASE 
             WHEN TYPE = 'Resolved' THEN 1 
             ELSE 0 
           END) number_resolved 
FROM   (SELECT dateassigned typedate, 
               'assinged'   AS TYPE 
        FROM   sampledata 
        WHERE  dateassigned IS NOT NULL 
        UNION ALL 
        SELECT datecompleted typedate, 
               'completed'   AS TYPE 
        FROM   sampledata 
        WHERE  datecompleted IS NOT NULL 
        UNION ALL 
        SELECT dateresolved typedate, 
               'Resolved'   AS TYPE 
        FROM   sampledata 
        WHERE  dateresolved IS NOT NULL) data 
GROUP  BY YEAR(typedate), 
          MONTH(typedate) 
ORDER  BY YEAR(typedate), 
          MONTH(typedate) 

The sub select creates two columns typedate and type

Which will look like this

typedate type
-------- ---------
1/1/2011 assinged
1/1/2011 assinged
1/1/2011 assinged
2/1/2011 completed
2/1/2011 completed
2/3/2011 Resolved

Then I used SUM(CASE... to pivot the data. If you're using a RDBMS that supports it you could use pivot instead

The final output looks something like this

                        Number_Assigned Number_completed Number_Resolved
----------- ----------- --------------- ---------------- ---------------
2011        1           3               0                0
2011        2           0               2                1

I'll leave it to you to do the formatting of the year and month