6

我有一个包含以下数据的表:

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 代码

4

4 回答 4

21

一些 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 ;

SQL-Fiddle进行测试


其他 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), ());

SQL-Fiddle-2上进行测试


@AndriyM 纠正了我,还有GROUP BY ROLLUP(由 Oracle 和 SQL-Server 实现),结果相同(参见上面更新的 SQL-Fiddle-2):

SELECT pk, name,
       SUM(score) AS score
FROM t
GROUP BY ROLLUP 
  (name, pk) ;
于 2013-10-15T17:56:35.593 回答
9

一般来说,它会是这样的:

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'

=> sql 小提琴演示

于 2013-10-15T17:53:34.520 回答
2

你所展示的更多的是一份报告。您可以使用应用程序逻辑或报告工具。第一个查询显示按玩家排序的值列表,第二个查询获取实际总和。

select
    name,
    score
from playerscore
order by name asc

select
    name,
    sum(score)
from playerscore
group by name
于 2013-10-15T17:50:17.957 回答
-3

SQL 并非旨在列出您的输出行,然后在每次行更改值时打印总计。这样的输出最好在应用程序级别完成,您可以按“A”对 SQL 输出进行排序,继续添加到分数列的小计,然后当应用程序检测到“B”的更改时,它会插入一行正如您在此处显示的那样,显示小计。然后它会在更改为“B”时重置小计。我将从 Select Name, Score from Table Order by Name 开始,然后在应用程序中处理其余部分。我真的会考虑您是否需要单个分数结果的行,因为如果您可以从此查询中跳过它们,那么您可以直接使用 SQL Server 进行总计,但您只能按名称获取总计。

于 2013-10-15T17:53:54.353 回答