SQL Server总计的运行摘要

时间:2018-07-18 08:28:38

标签: sql sql-server

遇到一个我想在查询中总结结果的问题。

示例如下:

NAME | FRUIT | PRICE 
-----+-------+------
JOHN | APPLE |  2
JOHN | APPLE |  2
JOHN | APPLE |  2
JOHN | APPLE |  2
DAVE | GRAPE |  3
DAVE | GRAPE |  3
DAVE | GRAPE |  3

这是我现在的桌子,尽管我需要的是约翰斯业务的摘要,如下所示:

NAME | FRUIT | PRICE 
-----+-------+------
JOHN | APPLE |  2
JOHN | APPLE |  2
JOHN | APPLE |  2
JOHN | APPLE |  2
JOHN | TOTAL |  8 
DAVE | GRAPE |  3
DAVE | GRAPE |  3
DAVE | GRAPE |  3
DAVE | TOTAL |  9

我试图对信息进行分组,但是它不能反映我想要的信息,此外,如果约翰要获得不同的成果,则需要对其进行汇总,然后再对下一部分进行汇总,并且需要有一个总计NAME字段中的所有值,因为会有很多客户。

任何建议都会很棒

编辑

我尝试使用汇总,但是我一直在单独的列中获取所有值的总和,正如我希望看到的那样,其格式如上

3 个答案:

答案 0 :(得分:3)

具有UNIONGROUP BY的解决方案。

;WITH PricesWithTotals AS
(
    SELECT
        Name,
        Fruit,
        Price
    FROM
        YourTable
    UNION ALL
    SELECT
        Name,
        Fruit = 'TOTAL',
        Price = SUM(Price)
    FROM
        YourTable
    GROUP BY
        Name
)
SELECT
    Name,
    Fruit,
    Price
FROM
    PricesWithTotals
ORDER BY
    Name,
    CASE WHEN Fruit <> 'Total' THEN 1 ELSE 999 END ASC,
    Fruit

答案 1 :(得分:1)

这将使您每个水果的每位客户的总营业额:

create table #Sales([Name] varchar(20), Fruit varchar(20), Price int)
insert into #Sales([Name], Fruit, Price)
values
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('JOHN','APPLE',2),
('DAVE','GRAPE',3),
('DAVE','GRAPE',3),
('DAVE','GRAPE',3)


Select c.*
, SUM(Price) OVER (PARTITION BY c.[Name], c.[Fruit] ORDER BY c.[Name], c.[Fruit] rows between unbounded preceding and current ROW ) as RunningTotal
from #Sales c
order by c.[Name], c.[Fruit] asc

drop table #Sales

输出:

enter image description here

答案 2 :(得分:0)

您的问题的解决方案是GROUPING SETS。但是,您的行不是唯一的。 las,这会增加一个唯一的值,这样您就可以保留原始行:

with t as (
      select t.*, row_number() over (order by (select null)) as seqnum
      from t
     )
select name, ,
       coalesce(fruit, 'Total') as fruit,
       sum(price) as price
from t
group by grouping sets ( (name, fruit, seqnum), (name) )
order by name,
      (case when fruit is not null then 1 else 2 end);