简体   繁体   中英

How can I GROUP BY Month and Year but then sort by the date as a date format in SQL?

I need to display to a user how many 'cases' they have submitted per month for use in a graphing application. The stored procedure simply grabs this data with the supplied unique ID for the user in the background.

This should be a simple GROUP BY to combine the dates, but I stumbled across a frustrating problem. Once I've grouped by 'MMM-yy', the ability to sort the data as a 'date' format is lost, as it alphabetically sorts the TEXT instead of the dates the text represent.

I have managed to achieve the sort with some fiddling in the query, but I lost the GROUP BY format and then replicates as 'Oct-20' and 'Oct-20' for two different dates.

I thought I'd finally cracked it with the below query, but the date sorting isn't correct still (appears to sort in some bizarre order that isn't date, numerical or text).

What is the correct way to GROUP BY in this format but still achieve a correct date sort?

   DECLARE @userID as int
       SET @userID = 123

    SELECT FORMAT(b.[occur_date], 'MMM-yy') as [Date],
        a1.[Total] as [Total1],
        a2.[Total] as [Total2],
        a3.[Total] as [Total3],
        a4.[Total] as [Total4]
      FROM [bugReports] as b

/*
-- A1 - A4 OUTER APPLY functions to get the totals here > --
*/

     WHERE 1=1
           AND b.[user_id] = @userID
           AND b.[occur_date] >= DATEADD(MONTH, -12, CURRENT_TIMESTAMP)
     GROUP BY
           (YEAR(b.[occur_date]) * 100) + MONTH(b.[occur_date]),
           FORMAT(b.[occur_date], 'MMM-yy'),
           a1.[Total],
           a2.[Total],
           a3.[Total],
           a4.[Total]
     ORDER BY
           (YEAR(b.[occur_date]) * 100) + MONTH(b.[occur_date]);

Desired Output

+--------+--------+--------+--------+--------+
|  Date  | Total1 | Total2 | Total3 | Total4 |
+--------+--------+--------+--------+--------+
| Oct-20 |     12 |     34 |     21 |     19 |
| Nov-20 |     22 |      5 |     11 |     16 |
| Dec-20 |     15 |      7 |     11 |     19 |
| Jan-21 |      5 |      9 |     13 |     29 |
| Feb-21 |     11 |     20 |     21 |     23 |
| ...    |     .. |     .. |     .. |     .. |
+--------+--------+--------+--------+--------+

If your issue is only ordering the results, I would suggest using an aggregation function:

ORDER BY MIN(b.occur_date)

It is unclear to my why you are using GROUP BY for this query. However, based on your question, I'm assuming that the query is working except for the ordering.

You can (and should) use EOMONTH to group, this returns the latest date in each month, but keeps it as a date

   DECLARE @userID as int
       SET @userID = 123

    SELECT FORMAT(EOMONTH(b.[occur_date]), 'MMM-yy') as [Date],
        a1.[Total] as [Total1],
        a2.[Total] as [Total2],
        a3.[Total] as [Total3],
        a4.[Total] as [Total4]
      FROM [bugReports] as b

/*
-- A1 - A4 OUTER APPLY functions to get the totals here > --
*/

     WHERE 1=1
           AND b.[user_id] = @userID
           AND b.[occur_date] >= DATEADD(MONTH, -12, CURRENT_TIMESTAMP)
     GROUP BY
           EOMONTH(b.[occur_date]),
           a1.[Total],
           a2.[Total],
           a3.[Total],
           a4.[Total]
     ORDER BY
           EOMONTH(b.[occur_date]);

Note that the formatting occurs only at the SELECT , not in the GROUP BY or ORDER BY

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM