不按分组汇总获胜者/失败者

时间:2020-11-12 01:46:15

标签: sql sql-server group-by window-functions

我遇到的一种情况是,我试图首先确定赢家和输家的销售人员(在任何时间段内),然后将结果汇总为总赢金额和总亏损金额。我可以使用CTE在下面完成此操作,但我觉得必须有一种方法可以在一个使用window函数或类似函数的语句中执行此操作。我在下面附加了一些示例数据。

有什么想法吗?

谢谢

drop table if exists #source

create table #source (
    region  varchar(25),
    salesperson varchar(25),
    amount  float,
    period_date date
)


insert into #source
select region, salesperson, amount, period_date
from  (values
('Americas','Johanna Vandervort', -200, '2020-01-01'),
('Americas','Dagmar Kuhn', 100, '2020-01-01'),
('Americas','Arno Schmitt', 300, '2020-01-01'),
('Americas','Matt Mayert', -500, '2020-01-01'),
('Asia','Alanna Brakus', 150, '2020-01-01'),
('Asia','Eldora Toy Jr.', 240, '2020-01-01'),
('Asia','Tate Reichert', -130, '2020-01-01'),
('Asia','Jacynthe Stark', 120, '2020-01-01'),
('Europe','Bette Armstrong', -600, '2020-01-01'),
('Europe','Neva Bogan', 300, '2020-01-01'),
('Europe','Jillian Windler', 200, '2020-01-01'),
('NJ Asia','Giovanni Prosacco', 550, '2020-01-01'),
('NJ Asia','Elise Heaney', -720, '2020-01-01'),
('NJ Asia','Cooper Prosacco', 140, '2020-01-01'),
('NJ Asia','Morton Steuber', 320, '2020-01-01'),
('Americas','Johanna Vandervort', -720, '2020-02-01'),
('Americas','Dagmar Kuhn', -600, '2020-02-01'),
('Americas','Arno Schmitt', -500, '2020-02-01'),
('Americas','Matt Mayert', -200, '2020-02-01'),
('Asia','Alanna Brakus', -130, '2020-02-01'),
('Asia','Eldora Toy Jr.', 100, '2020-02-01'),
('Asia','Tate Reichert', 120, '2020-02-01'),
('Asia','Jacynthe Stark', 140, '2020-02-01'),
('Europe','Bette Armstrong', 150, '2020-02-01'),
('Europe','Neva Bogan', 200, '2020-02-01'),
('Europe','Jillian Windler', 240, '2020-02-01'),
('NJ Asia','Giovanni Prosacco', 300, '2020-02-01'),
('NJ Asia','Elise Heaney', 300, '2020-02-01'),
('NJ Asia','Cooper Prosacco', 320, '2020-02-01'),
('NJ Asia','Morton Steuber', 550, '2020-02-01')
) as t(region, salesperson, amount, period_date)

with src as (
    -- first aggregating to salesperson grain across time period and segregating winners and losers
    select  case when sum(amount) > 0 then sum(amount) else 0 end as winner_sales
            ,case when sum(amount) <= 0 then sum(amount) else 0 end as loser_sales
            , salesperson
            , region 
    from #source 
    group by 
            region
            , salesperson
)
-- then aggregating results into total winners and total losers
select sum(winner_sales) as winner_sales, sum(loser_sales) as loser_sales, region
from src
group by region

1 个答案:

答案 0 :(得分:1)

无论您做什么,都可以。您不能将它们放在单个查询中,当您尝试将其放入时,将得到以下错误。

消息4109,级别15,状态1,第64行无法使用窗口功能 在另一个窗口函数或集合的上下文中。

我放置了派生表,使其看起来像单个查询。

SELECT region,sum(CASE WHEN total_sales > 0 THEN total_sales else 0 end) as winner_sales,
sum(CASE WHEN total_sales < 0 THEN total_sales else 0 end) as loser_sales
from
(SELECT region,
 sum(amount) OVER(PARTITION BY region,salesperson) as total_sales
from #SOURCE) as t
group by region

+----------+--------------+-------------+
|  region  | winner_sales | loser_sales |
+----------+--------------+-------------+
| Americas |            0 |       -4640 |
| Asia     |         1240 |         -20 |
| Europe   |         1880 |        -900 |
| NJ Asia  |         4360 |        -840 |
+----------+--------------+-------------+