Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Query that Groups Multiple Date Fields

Tags:

sql

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.

like image 963
j0nnyf1ve Avatar asked Aug 06 '11 21:08

j0nnyf1ve


People also ask

Can we GROUP BY date in SQL?

Group by in Date fieldHere we can apply group by command on our date field. Along with the group by command we can use count command to count total number of records in each day. We will discuss some SQL examples using some examples.

Can you GROUP BY two fields in SQL?

We can use the group by multiple column technique to group multiple records into a single record. All the records that have the same values for the respective columns mentioned in the grouping criteria can be grouped as a single column using the group by multiple column technique.

Can we do GROUP BY on multiple columns?

Yes, it is possible to use MySQL GROUP BY clause with multiple columns just as we can use MySQL DISTINCT clause.


1 Answers

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

like image 78
Conrad Frix Avatar answered Oct 23 '22 01:10

Conrad Frix