SELECT 语句以获取具有列标题的分组列的总和

Posted

技术标签:

【中文标题】SELECT 语句以获取具有列标题的分组列的总和【英文标题】:SELECT statement to get sum of grouped columns with column header 【发布时间】:2015-01-21 10:57:27 【问题描述】:

表格数据:

NAME     RS
A        10
A        20
A        30
B        15 
B        5
B        10
C        70
C        30 

预期输出:

A   -- column name
10
20
30
60  -- total of A

B
15
5
10 
30  -- total of B

C
70
30
100 -- total of C

到目前为止我已经尝试过:

    UNION ALL 选择所有数据并使用前端进行操作。

没有UNION ALL,还有其他最简单的解决方案吗?

【问题讨论】:

组名作为标题行,并找到分组总 Rs 的总和(例如-10+20+30=60)。(一切都应该作为行返回)。我现在清楚了吗跨度> 您仍在为A 列出单独的行,但没有为C 列出,这是不清楚的部分。 请编辑问题以将实际预期结果呈现为预期结果。 抱歉我更新了我的问题 【参考方案1】:

使用普通 SQL 在单个查询中执行此操作:

SELECT unnest(arr)
FROM  (
   SELECT ARRAY[name] || array_agg(rs::text) || sum(rs)::text AS arr
   FROM   tbl
   GROUP  BY name
   ) sub
ORDER  BY arr[1];

类似于@WingedPanther 发布的内容,但对任何名称都干净且安全。

返回:

A
10
20
30
60
B
15
15
C
70
30
100

或者:

WITH cte AS (
   SELECT name, sum(RS)::text AS sum_rs
   FROM   tbl
   GROUP  BY 1
   )
SELECT unicol
FROM  ( 
   SELECT name AS unicol, name AS order1, 1 AS order2 FROM cte
   UNION  ALL
   SELECT sum_rs, name, 2 FROM cte
   ) sub
ORDER  BY order1, order2;

返回:

A
60
B
15
C
100

SQL Fiddle.

或者只是从 CTE 发送结果,其余的交给您的客户。

【讨论】:

感谢您的回复。我需要像 A 10 20 30 (10 + 20 + 30 = 60) 这样的输出【参考方案2】:

试试这个

select  unnest(string_to_array( name ||','||rs||','||sum, ',')) AS elem 
from (
     select name
           ,string_agg(rs::text,',')  rs
           ,sum(rs) 
     from tbl 
     group by name
)t 

如果您想在 Result 中打印 Total Of,请使用

select  unnest(string_to_array( name ||','||rs||','||sum, ',')) AS elem 
from (
     select name
           ,string_agg(rs::text,',')  rs
           ,'Total Of '||name||' '|| sum(rs) sum
     from tbl 
     group by name
)t 

> SQLFIDDLE

【讨论】:

我喜欢取消嵌套数组 (+1) 的想法。但是使用字符串连接是不安全的 - 只需构建一个数组开始,然后你就不用依赖分隔符了。 @ErwinBrandstetter 感谢您的建议,您已经在回答中提到了这一点,所以我不想更新我的回答(以便未来的访问者可以轻松理解)【参考方案3】:

不是 100% 确定你在追求什么,但听起来你只是想要这个:

Select name, Sum(RS)
from sometable
group by name

【讨论】:

【参考方案4】:

试试这个:

DECLARE @t TABLE(Name NVARCHAR(MAX), RS INT)

INSERT INTO @t VALUES
('A', 10),
('A', 20),
('A', 30),
('B', 15),
('C', 70),
('C', 30)

使用联合

SELECT Name, RS, 0 AS OrderBit FROM @t
UNION ALL
SELECT Name, SUM(RS) AS Total, 1 AS OrderBit FROM @t
GROUP BY Name

ORDER BY Name, OrderBit

没有联合:

SELECT Name, SUM(RS) AS RS FROM @t 
GROUP BY GROUPING SETS((Name), (Name, RS))

【讨论】:

GROUPING SETS 可以在 postgresql 中使用吗? 我不知道 POSTGRESQL 但似乎有可能。 wiki.postgresql.org/wiki/Grouping_Sets Postgres 的语法无效。 @ErwinBrandstetter 你在开玩笑吗?小提琴的结果你有数据INSERT INTO tbl VALUES ('A', 10), ('A', 20), ('A', 30), ('B', 15), ('C', 70), ('C', 30) 输出是A 10 0 A 20 0 A 30 0 A 60 1 B 15 0 B 15 1 C 70 0 C 30 0 C 100 1 这里有什么不正确的? 该问题从一开始就被标记为[postgresql]。检查edit history。您的其他索赔也是如此。仅当您 @-reply 时才会通知我。我已经完成了,祝你有美好的一天。

以上是关于SELECT 语句以获取具有列标题的分组列的总和的主要内容,如果未能解决你的问题,请参考以下文章

如何按一列的最大值获取SQL行,按另一列分组

以日历季度为列分组

如何根据不同的分组条件得到两个数量列的总和?

data.table 分组所有列的总和

熊猫:设置列等于另一列的分组总和[重复]

动态列的水平总和