如何在sql中添加小计行

时间:2013-10-15 17:44:59

标签: 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代码

4 个答案:

答案 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 ;

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) ;

答案 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服务器完成你的总计,但你只能按名称得到总数。