我有一张包含以下数据的表格:
Name Score
A 2
B 3
A 1
B 3
我想要一个提供以下输出的查询。
Name Score
A 2
A 1
Subtotal 3
B 3
B 3
Subtotal 6
请帮我一个SQL代码
答案 0 :(得分:17)
某些DBMS(如MySQL和SQL-Server)具有WITH ROLLUP
子句的GROUP BY
修饰符,可用于此类查询:
SELECT pk, name,
SUM(score) AS score
FROM tableX
GROUP BY name, pk -- pk is the PRIMARY KEY of the table
WITH ROLLUP ;
进行测试
其他DBMS(SQL-Server,Oracle)已经实现了可以使用的GROUP BY GROUPING SETS
功能(并且比WITH ROLLUP
更强大):
SELECT pk, name,
SUM(score) AS score
FROM tableX
GROUP BY GROUPING SETS
((name, pk), (name), ());
进行测试
GROUP BY ROLLUP
(由Oracle和SQL-Server实现),结果相同(参见上面更新的SQL-Fiddle-2):
SELECT pk, name,
SUM(score) AS score
FROM t
GROUP BY ROLLUP
(name, pk) ;
答案 1 :(得分:7)
一般来说,它会是这样的:
select Name, Score
from (
select Name, Score, Name as o
from Table1 as a
union all
select 'Subtotal', sum(Score), Name as o
from Table1 as a
group by Name
) as a
order by o, score
但是,正如@ypercube所说,不同的RDBMS中有不同的具体实现。您的任务有点复杂,因为您的表没有主键,因此您可以使用row_number()函数来模拟它。对于SQL Server,您可以使用grouping sets:
with cte as (
select *, row_number() over(order by newid()) as rn
from Table1
)
select
case
when grouping(c.rn) = 1 then 'Subtotal'
else c.Name
end as Name,
sum(c.Score) as Score
from cte as c
group by grouping sets ((c.Name), (c.Name, c.rn))
order by c.Name;
或rollup():
with cte as (
select *, row_number() over(order by newid()) as rn
from Table1
)
select
case
when grouping(c.rn) = 1 then 'Subtotal'
else c.Name
end as Name,
sum(c.Score) as Score
from cte as c
group by rollup(c.Name, c.rn)
having grouping(c.Name) = 0
order by c.Name;
请注意grouping()函数将name
列替换为静态'Subtotal'
字符串。另请注意,列的顺序在rollup()查询中很重要。
<强> => sql fiddle demo 强>
答案 2 :(得分:1)
您所展示的更多是一份报告。您可以使用应用程序逻辑或报告工具。第一个查询显示按玩家排序的值列表,第二个查询获取实际总和。
select
name,
score
from playerscore
order by name asc
select
name,
sum(score)
from playerscore
group by name
答案 3 :(得分:-4)
SQL不是为了列出输出行而设计的,然后每次行更改值时都会打印一次。这样的输出最好在应用程序级别完成,您可以在其中按“A”排序SQL输出,继续在分数列上添加小计,然后当应用程序检测到更改为“B”时,它将插入一行正如您在此处所示,显示小计。然后它会在更改为“B”时重置小计。我将从选择名称开始,从表顺序得分,然后处理应用程序中的其余部分。我真的会考虑你是否需要单独得分结果的行,因为如果你可以从这个查询中跳过它们,那么你可以直接用SQL服务器完成你的总计,但你只能按名称得到总数。