【问题标题】:SQL Grand Total row from Multi table Select Query多表选择查询中的 SQL 总计行
【发布时间】:2020-03-18 19:43:28
【问题描述】:

我已经能够使用下面的 SQL 查询给我 4 行数据

SELECT 'Sales Order ' as Type, Format(Sum(T1.C_NetAmountLessDiscount), 
'#.00') As NetAmount, Format(Sum(T1.C_MarginAmount), '#.00') As 
MarginAmount, Format(Sum(T1.C_MarginAmount)/Sum(T1.C_NetAmountLessDiscount), 
'#.00%') As Margin
From T_SalesOrder as T1
Where cast(T1.C_Date as Date) = cast(getdate() as Date) AND T1.C_OrderType 
!= 'BK' AND T1.C_OrderType != 'INV'

Union

SELECT 'Despatch Notes ' AS Type, Format(Sum(T1.C_NetAmountLessDiscount), 
'#.00') As NetAmount, Format(Sum(T1.C_MarginAmount), '#.00') As 
MarginAmount, Format(Sum(T1.C_MarginAmount)/Sum(T1.C_NetAmountLessDiscount), 
'#.00%') As Margin
From T_SalesDeliveryNote as T1
Where cast(T1.C_Date as Date) = cast(getdate() as Date) AND T1.C_Order is 
null AND T1.C_BillingStatus = '0'

Union

SELECT 'Invoices ' AS Type, Format(Sum(T1.C_NetAmountLessDiscount), '#.00') 
As NetAmount, Format(Sum(T1.C_MarginAmount), '#.00') As MarginAmount, 
Format(Sum(T1.C_MarginAmount)/Sum(T1.C_NetAmountLessDiscount), '#.00%') As 
Margin
From T_SalesInvoice as T1
Where cast(T1.C_Date as Date) = cast(getdate() as Date) And 
T1.C_DeliveryNote is null And T1.C_SourceOrder is null and T1.C_InvoiceType 
= '0'

Union

SELECT 'Credit Notes ' AS Type, Format(Sum(T1.C_NetAmountLessDiscount), '- 
#.00') As NetAmount, Format(Sum(T1.C_MarginAmount), '-#.00') As 
MarginAmount, Format(Sum(T1.C_MarginAmount)/Sum(T1.C_NetAmountLessDiscount), 
'#.00%') As Margin
From T_SalesCreditNote as T1
Where cast(T1.C_Date as Date) = cast(getdate() as Date)

这为我提供了我需要的订单明细,但我还希望有一个总计行来对每一列求和。

如果我将上面的 sql 查询插入到下面

Select 'Grand Total', Sum(CAST(NetAmount AS float)), Sum(CAST(MarginAmount 
AS float)),null
From
(
-----Above SQL Query in Here
)tbl

我得到一个包含正确总数但没有细分行的单行。

我该怎么做才能显示每种类型的四行和底部的总计行。

【问题讨论】:

  • 你用的是什么关系型数据库?
  • 嗨 JNevill,这是使用 MS SQL Server 2012
  • 也许你可以添加到一个临时表来保存四行并将四行结果评估为最后一行。然后您可以返回临时表
  • 看看 GROUPING SETS... 例如stackoverflow.com/questions/56827331/…
  • 嗨约翰,这给了我我需要的东西,谢谢。只需要能够在类型列中添加一个名称(即总计),但似乎找不到这样做的方法。

标签: sql sql-server sql-server-2012


【解决方案1】:

使用common table expressions (CTE)。

WITH t AS(
    -- Your query goes here
    -- SELECT 1 AS A, 'Sales Order' ...
    -- UNION SELECT 2 AS A, 'Despatch Notes' ...
    -- UNION SELECT 3 AS A, 'Invoices' ...
    -- UNION SELECT 4 AS A, 'Credit Notes' ...
)
SELECT
    A,
    Type,
    NetAmount,
    MarginAmount,
    Margin
FROM
    t
UNION SELECT
    5 AS A,
    'Grand Total' AS Type,
    FORMAT(SUM(CAST(NetAmount AS FLOAT)), '#.00') As NetAmount,
    FORMAT(SUM(CAST(MarginAmount AS FLOAT)), '#.00') As MarginAmount,
    NULL
FROM
    t
ORDER BY
    A

注意:我添加了总值的格式以确保 NetAmount 和 MarginAmount 的总值与细分值共享相同的数据类型。考虑从查询中删除值的格式并将其添加到应用程序的表示层。

【讨论】:

  • 嗨 Pilosa,这几乎完全满足了我的要求,但因为这是按类型排序的,所以总行位于中间。您知道如何按照与我查询中的选择相同的方式进行排序吗?
  • 您可以添加一列(请参阅我更新的答案中的 A 列)来对行进行排序。
【解决方案2】:

使用ROLLUP 分组可能只是解决此问题的窍门。

简化示例片段:

DECLARE @Table1 TABLE (
 ID INT IDENTITY(1,1) PRIMARY KEY,
 Name VARCHAR(30) NOT NULL,
 NetAmount DECIMAL(10,2) NOT NULL DEFAULT 0
);

DECLARE @Table2 TABLE (
 ID INT IDENTITY(1,1) PRIMARY KEY,
 Name VARCHAR(30) NOT NULL,
 NetAmount DECIMAL(10,2) NOT NULL DEFAULT 0
);

INSERT INTO @Table1 (Name, NetAmount) 
VALUES ('A', 4.1), ('A', 6.1);

INSERT INTO @Table2 (Name, NetAmount) 
VALUES ('B', 9.1), ('B', 11.1);

WITH CTE_AMOUNTS AS
(
    SELECT 'T1' as [Type],
    SUM(NetAmount) AS [NetAmount]
    FROM @Table1

    UNION ALL

    SELECT 'T2', SUM(NetAmount)
    FROM @Table2
)
SELECT 
COALESCE([Type], 'Grand Total') AS [Type],
SUM([NetAmount]) AS [NetAmount]
FROM CTE_AMOUNTS
GROUP BY Type WITH ROLLUP
ORDER BY GROUPING_ID(Type), Type;

返回:

Type        NetAmount
T1          10,20
T2          20,20
Grand Total 30,40

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多