SQL为每个属性添加总和行

Posted

技术标签:

【中文标题】SQL为每个属性添加总和行【英文标题】:SQL Add total sum row for each property 【发布时间】:2020-04-16 08:05:56 【问题描述】:

我正在尝试为每个州创建一个新的总和行。

示例表:

| State | Item | Amount
    A      X      100
    B      Y      200
    A      Z      100
    B      X      150

结果:

| State | Item | Amount
    A      X      100
    A      Z      100
 Total A          200
    B      Y      200
    B      X      150
 Total B          350

是否有我可以用来执行该表的 SQL 查询

【问题讨论】:

您是否特别想在 SQL 中执行此操作?你可以在你的 C# 代码中执行它吗(例如通过 SQL 中的ORDER BY State 并在 C# 中按顺序处理它)? 您的 DBMS 版本是多少?有些支持GROUP BY 上的WITH ROLLUP 子句,它可以做你想做的事 @mjwills 是的,我可以用 C# 代码做到这一点,现在我只像在表 1 中那样循环表。我也看过这篇文章 (***.com/questions/17813580/…) 但我不知道怎么做从我的 SQL 中获取参数 @Nick 2014 年第 12 版 @Nick SQL Server 抱歉 【参考方案1】:

试试下面的查询。

SELECT * FROM states_YourtableName
    UNION
    SELECT 'Total '+[state] State ,'' Item ,SUM(Amount) Amount
    FROM states_YourtableName GROUP BY [State]

你会得到如下输出

state   Item    Amount
A        X      100
A        Z      100
B        X      150
B        Y      200
Total A         200
Total B         350

【讨论】:

这应该是UNION ALL。然后你应该想办法对结果行进行排序。使用当前查询,您可以获得任何订单(例如 Total B、A | Z、B | X | Total B、...)。按第一个结果列排序也不行,因为您会得到 A、B、Total A、Total B、Z、Total Z。【参考方案2】:

在 SQL Server 中,您可以在 GROUP BY 子句上使用 ROLLUP 来获取按字段分组的中间和总和。在您的情况下,您将按状态和项目分组以获取所有行:

SELECT CASE WHEN State IS NULL THEN 'Grand Total'
            WHEN Item IS NULL THEN CONCAT('Total ', State)
            ELSE State
       END AS State,
       Item, 
       SUM(Amount) AS Amount
FROM data
GROUP BY ROLLUP(State, Item)

输出:

State           Item    Amount
A               X       100
A               Z       100
Total A         (null)  200
B               X       150
B               Y       200
Total B         (null)  350
Grand Total     (null)  550

Demo on SQLFiddle

【讨论】:

ROLLUP 保证结果是这样排序的吗?我试图查找这个,但还没有找到答案。在那里的文档(docs.microsoft.com/de-de/sql/t-sql/queries/…)中,他们似乎认为这个命令是理所当然的,但没有明确提及。然而,据我所知,只有当我们应用ORDER BY 子句时,才能保证每个查询结果都是有序的。 @ThorstenKettner 同意;排序仅由文档暗示,但以任何其他方式输出它确实没有任何意义。【参考方案3】:

最简单的方法是UNION ALL。如果显示状态而不是“Total ”就足够了,则变为:

select state, item, amount from mytable
union all
select state, null, sum(amount) from mytable group by state
order by state, case when item is null then 2 else 1 end, item;

结果:

状态 |项目 |数量 ------+------+------ 一个 | X | 100 一个 | Z | 100 一个 | | 200 乙|是 | 200 乙| X | 150 乙| | 350

【讨论】:

【参考方案4】:

SQL 不是作为 excel 文件工作的,它主要用于存储和处理数据。如果您想在 SQL 中存储该数据(总计),我认为最好的方法是创建另一个可以保存总计的表。

如果您只想在屏幕上打印总数,您可以查看链接https://www.w3schools.com/sql/sql_count_avg_sum.asp

【讨论】:

【参考方案5】:

您可以将 group by 与 Rollup 一起使用

试试这个 -

declare @Data table
([State] varchar(20), Item varchar(20), Amount int )

Insert into @Data
values
(    'A',      'X',      100),
(    'B',      'Y',      200),
(    'A',      'Z',      100),
(    'B',      'X',      150)

Select [State], Item, Sum(Amount) Amount
From @Data
Group by [State], Item with Rollup

【讨论】:

【参考方案6】:

我推荐grouping sets。它提供了比rollup更多的控制:

select state, coalesce(item, 'Total') as item,
       sum(amount) as amount
from t
group by grouping sets ( (state, item), (state) );

【讨论】:

以上是关于SQL为每个属性添加总和行的主要内容,如果未能解决你的问题,请参考以下文章

将 SQL 查询转换为 JPQL 查询 - 总和具有特定文本值的属性数

Laravel Eloquent:获取嵌套关系中的数据总和并将其添加为新属性

行项目表的总和 SQL 子查询

返回每个模型的属性总和的计算属性

SQL Server 数据库中使用扩展属性的动态行级安全性

为每个查询的元素添加属性集