我有一个包含以下数据的表:
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 代码
我有一个包含以下数据的表:
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 代码
一些 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), ());
@AndriyM 纠正了我,还有GROUP BY ROLLUP
(由 Oracle 和 SQL-Server 实现),结果相同(参见上面更新的 SQL-Fiddle-2):
SELECT pk, name,
SUM(score) AS score
FROM t
GROUP BY ROLLUP
(name, pk) ;
一般来说,它会是这样的:
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,您可以使用分组集:
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;
或汇总():
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()函数。另请注意,列的顺序在 rollup() 查询中很重要。name
'Subtotal'
你所展示的更多的是一份报告。您可以使用应用程序逻辑或报告工具。第一个查询显示按玩家排序的值列表,第二个查询获取实际总和。
select
name,
score
from playerscore
order by name asc
select
name,
sum(score)
from playerscore
group by name
SQL 并非旨在列出您的输出行,然后在每次行更改值时打印总计。这样的输出最好在应用程序级别完成,您可以按“A”对 SQL 输出进行排序,继续添加到分数列的小计,然后当应用程序检测到“B”的更改时,它会插入一行正如您在此处显示的那样,显示小计。然后它会在更改为“B”时重置小计。我将从 Select Name, Score from Table Order by Name 开始,然后在应用程序中处理其余部分。我真的会考虑您是否需要单个分数结果的行,因为如果您可以从此查询中跳过它们,那么您可以直接使用 SQL Server 进行总计,但您只能按名称获取总计。