简体   繁体   中英

SQL Statement With 'Totals' as Final Column

I'm trying to run an SQL query with the first column being 'month'. Each column will have a number value (or the month number) and the final column will say 'Totals'. The issue is that when I try to have them order, it gives me errors every time it reaches the Totals column because it is looking for an INT value. So, for example, I have this query:

SELECT CY.Month, CY.PaymentAmount_ThisYear, LY.PaymentAmount_LastYear FROM
(SELECT DATEPART(MM, Orders.OrderDate) AS Month, SUM(Orders.PaymentAmount) as PaymentAmount_ThisYear 
    FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -1, CURRENT_TIMESTAMP))
    GROUP BY DATEPART(MM, Orders.OrderDate)
) CY
INNER JOIN 
(SELECT DATEPART(MM, Orders.OrderDate) AS Month, SUM(Orders.PaymentAmount) as PaymentAmount_LastYear
    FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -13, CURRENT_TIMESTAMP))
    GROUP BY DATEPART(MM, Orders.OrderDate)
) LY
ON CY.Month = LY.Month
UNION
SELECT 'Totals' AS Month, CY.PaymentAmount_ThisYear, LY.PaymentAmount_LastYear FROM
(SELECT SUM(Orders.PaymentAmount) AS PaymentAmount_ThisYear
    FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -1, CURRENT_TIMESTAMP))
) CY,
(SELECT SUM(Orders.PaymentAmount) AS PaymentAmount_LastYear
    FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -13, CURRENT_TIMESTAMP))
) LY

If I changed 'Totals' to 13, it works and puts the totals at the bottom but the row says '13' instead of 'Totals'.

在此处输入图片说明

So what I then tried was at the very beginning of the query I changed this:

SELECT CY.Month

To

SELECT CAST(CY.Month AS VARCHAR(10)) AS Month

But when I do that it orders them wrong it goes:

1
10
11
5

Because it's recognizing them as varchar values. I'm basically looking for this to order the months numerically but then have the last column say 'Totals'.

I also tried to do an

ORDER BY CASE ISNUMERIC(Month) WHEN 1 THEN CAST(Month AS INT) ELSE Month END

But that was giving me an 'Ambiguous column name 'Month'.' error.

I'm sort of stuck, any ideas? Thank you!

I think you can simplify your query considerably and use the ROLLUP option of GROUP BY to do your totals, eg:

SELECT 
      CASE 
        WHEN GROUPING(MONTH(orders.orderdate)) = 1 
        THEN 'Totals' 
        ELSE CONVERT(CHAR(2), MONTH(orders.orderdate)) 
      END AS [Month]
    , SUM(
        CASE 
            WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -1, CURRENT_TIMESTAMP)) 
            THEN orders.paymentamount 
            ELSE 0.00
        END
        )   AS PaymentAmount_ThisYear 
    , SUM(
        CASE 
            WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -13, CURRENT_TIMESTAMP)) 
            THEN orders.paymentamount 
            ELSE 0.00 
        END
        )   AS PaymentAmount_LastYear 
FROM   
    orders 
GROUP BY   
    MONTH(orders.orderdate)
WITH ROLLUP

You could try putting the current query in an inline view and then ordering afterwards

SELECT Month, PaymentAmount_ThisYear, PaymentAmount_LastYear
FROM (
    SELECT CAST(CY.Month AS VARCHAR(10)) AS Month, CY.PaymentAmount_ThisYear, LY.PaymentAmount_LastYear FROM
        (SELECT DATEPART(MM, Orders.OrderDate) AS Month, SUM(Orders.PaymentAmount) as PaymentAmount_ThisYear 
            FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -1, CURRENT_TIMESTAMP))
            GROUP BY DATEPART(MM, Orders.OrderDate)
        ) CY
    INNER JOIN 
        (SELECT DATEPART(MM, Orders.OrderDate) AS Month, SUM(Orders.PaymentAmount) as PaymentAmount_LastYear
            FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -13, CURRENT_TIMESTAMP))
            GROUP BY DATEPART(MM, Orders.OrderDate)
        ) LY
    ON CY.Month = LY.Month
    UNION
    SELECT 'Totals' AS Month, CY.PaymentAmount_ThisYear, LY.PaymentAmount_LastYear FROM
        (SELECT SUM(Orders.PaymentAmount) AS PaymentAmount_ThisYear
            FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -1, CURRENT_TIMESTAMP))
        ) CY,
        (SELECT SUM(Orders.PaymentAmount) AS PaymentAmount_LastYear
            FROM Orders WHERE DATEPART(YY, Orders.OrderDate) = DATEPART(YY, DATEADD(MM, -13, CURRENT_TIMESTAMP))
        ) LY) T
ORDER BY CASE WHEN ISNUMERIC(Month) = 1 THEN 0 ELSE 1 END, Month

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