【问题标题】:SQL Statement With 'Totals' as Final Column以“总计”作为最后一列的 SQL 语句
【发布时间】:2015-11-24 23:39:08
【问题描述】:

我正在尝试运行第一列为“月”的 SQL 查询。每列都有一个数值(或月份),最后一列将显示“总计”。问题是,当我尝试让它们排序时,每次到达 Totals 列时都会出错,因为它正在寻找一个 INT 值。所以,例如,我有这个查询:

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

如果我将“总计”更改为 13,它会起作用并将总计放在底部,但该行显示“13”而不是“总计”。

然后我尝试的是在查询的最开始我更改了这个:

SELECT CY.Month

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

但是当我这样做时,它会错误地命令它们:

1
10
11
5

因为它将它们识别为 varchar 值。我基本上是在寻找这个以数字顺序排列月份,但最后一列说“总计”。

我也试过了

订购方式 CASE ISNUMERIC(月) WHEN 1 THEN CAST(月份为 INT) 其他月份 结束

但这给了我一个“不明确的列名‘月份’。”错误。

我有点卡住了,有什么想法吗?谢谢!

【问题讨论】:

  • 是否有理由让最后一行成为总行?这类事情应该使用您的显示代码或在您将其导出到电子表格后完成。
  • @TonyDeStefano,是的,问题是我们是在 Volusion 框架(电子商务)中做的。问题是您有一个窗口,您可以在其中执行 SELECT 查询,因此它不是通过任何类型的“显示代码”完成的,它只是执行查询并以 CSV 格式输出。我们希望最后的总数的原因是它是为客户服务的,我们只希望它为他们单击一次。似乎这是可能的,我已经通过这些不同的尝试非常接近了......我觉得我只是一个小小的改变,但在任何地方都找不到。
  • 你可以用零填充一位数的月份,这样它就可以像这样对它们进行排序:01、02、03 ... 11、12、Totals?

标签: mysql sql-server


【解决方案1】:

我认为您可以大大简化您的查询并使用 GROUP BY 的 ROLLUP 选项来进行总计,例如:

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

【讨论】:

  • 太棒了。谢谢!我有几件事要添加,所以这是开始第一部分的完美之选。绝对比我们的思维方式干净得多。
【解决方案2】:

您可以尝试将当前查询放在内联视图中,然后再进行排序

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多