sql-server 使用CTE和UNION ALL查询,总计在底部

hiz5n14c  于 2022-10-31  发布在  其他
关注(0)|答案(2)|浏览(170)

这是我正在尝试的SQL Server查询的简化版本或代表:

WITH T1 AS (
    SELECT DocNum, CardCode, CardName FROM OINV
)
SELECT CardName AS 'Customer Name', DocNum FROM T1
UNION ALL
SELECT 'Grand Total', COUNT(DocNum) FROM T1
ORDER BY "Customer Name"

在真实的的查询中,我无法避免使用CTE,因为我需要在同一查询中引用另一个CTE中的一个CTE的结果,并且存在多个CTE。
我的主要要求是在查询的末尾有一个“总计”行。"总计“行将显示一些汇总数字,如”计数“、”总和“等。在真实的查询中,"总计”行本身将根据CTE结果之一导出其汇总数字。
在上面的简化查询中,如何在查询结果中不添加任何额外列的情况下,实现查询底部的总计。
在我的真实的查询中,第一个CTE获得所有单据的列表,以及它们的未清余额和账龄天数;
第二个查询通过连接几个其他表来添加附加列,并将未清金额分类到帐龄时段,如0-30天、30-60天等
我需要向第二个查询的结果中添加一个“总计”行,它应该提供所有客户的未付总额以及CTE 2中分类的每个帐龄时段的总额。

0yg35tkg

0yg35tkg1#

你通常会在你的前端计算出你的总数等。
但如果必须这样做,为什么不能在从CTE中选择时使用子查询,例如

WITH T1 AS (
    SELECT DocNum, CardCode, CardName
    FROM OINV
)
SELECT [Customer Name], DocNum
FROM
    SELECT CardName AS [Customer Name], DocNum, 0 OrderBy
    FROM T1
    UNION ALL
    SELECT 'Grand Total', COUNT(DocNum), 1 OrderBy
    FROM T1
) X
ORDER BY OrderBy ASC, [Customer Name];

注:不要使用单引号来表示列名。请使用双引号或方括号。

8ehkhllq

8ehkhllq2#

您可以使用GROUPING SETS来执行此操作,并且它只需要对基表/CTE进行一次扫描

WITH T1 AS (
    SELECT DocNum, CardCode, CardName
    FROM OINV
)
SELECT
  CASE WHEN GROUPING(CardName) = 0 THEN CardName ELSE 'GrandTotal' END AS CardName,
  CASE WHEN GROUPING(CardName) = 0 THEN DocNum   ELSE CAST(COUNT(*) AS varchar(30)) END AS DocNum
FROM T1
GROUP BY GROUPING SETS (
    (CardName, DocNum),
    ()
)
ORDER BY
  GROUPING(CardName),
  CardName;

相关问题