Sql 为聚合列添加小计列

Sql 为聚合列添加小计列,sql,sql-server,aggregate-functions,window-functions,Sql,Sql Server,Aggregate Functions,Window Functions,以下是我的交易、交易员和交易对手数据集: TRADER_ID | TRADER_NAME | EXEC_BROKER | TRADE_AMOUNT | TRADE_ID ABC123 | Jules Winnfield | GOLD | 10000 | ASDADAD XDA241 | Jimmie Dimmick | GOLD | 12000 | ASSVASD ADC123 | Vincent

以下是我的交易、交易员和交易对手数据集:

TRADER_ID  | TRADER_NAME     | EXEC_BROKER | TRADE_AMOUNT  | TRADE_ID
    ABC123 | Jules Winnfield | GOLD        | 10000         | ASDADAD
    XDA241 | Jimmie Dimmick  | GOLD        | 12000         | ASSVASD
    ADC123 | Vincent Vega    | BARC        | 10000         | ZXCZCX
    ABC123 | Jules Winnfield | BARC        | 15000         | ASSXCQA
    ADC123 | Vincent Vega    | CRED        | 250000        | RFAQQA
    ABC123 | Jules Winnfield | CRED        | 5000          | ASDQ23A
    ABC123 | Jules Winnfield | GOLD        | 5000          | AVBDQ3A
我希望生成一份可重复的月度报告,以查看交易对手(EXEC_BROKER字段)层面的交易活动汇总情况,并提供小计,如下所示:

TRADER_ID | TRADER_NAME | NO._OF_CCP_USED | CCP | TRADED_AMT_WITH_CCP | VALUE_OF_TOTAL_TRADES | TRADES_WITH_CCP | TOTAL_TRADES
    ABC123 | Jules Winnfield | 3 | GOLD | 15000 | 35000 | 2 | 4
    ABC123 | Jules Winnfield | 3 | BARC | 15000 | 35000 | 1 | 4
    ABC123 | Jules Winnfield | 3 | CRED | 5000 | 35000 | 1 | 4
……等等

我们的想法是汇总每个交易对手的交易数量(我使用了计数函数),以及与ccp的交易金额之和,但我很难获得每个交易对手旁边的“小计”字段,如上面我的期望输出所示-因此,你可以在这里看到Jules总共与3个交易对手打过交道,他们之间有4个交易,总金额为35000

我尝试过使用聚合函数和overby函数的组合,但没有效果

SELECT
     OT.TRADER_ID,
     OT.TRADER_NAME,
     OT.EXEC_BROKER,
     SUM(OT.TRADE_AMOUNT) AS VALUE_OF_TOTAL_TRADES,
     COUNT(OT.TRADE_ID) AS TOTAL_TRADES,
     COUNT(OT.EXEC_BROKER) OVER PARTITION BY (OT.TRADER_ID) AS NO._OF_CCP_USED, 
     SUM(OT.TRADE_AMOUNT) OVER PARTITION BY (OT.EXEC_BROKER) AS TRADED_AMT_WITH_CCP,
     COUNT(OT.TRADE_ID) OVER PARTITION BY (OT.EXEC_BROKER) AS TRADES_WITH_CCP

FROM dbo.ORDERS_TRADES OT

GROUP BY OT.TRADER_ID, OT.TRADER_NAME, OT.EXEC_BROKER, OT.TRADE_AMOUNT, OT.TRADE_ID
上面的代码运行,但返回数百万行。当我逐行删除分区时,我得到的结果减去我要查找的小计列

有什么建议吗?非常感谢

编辑:

最终的代码为我提供了所需的输出:更新我的问题以提供此响应(感谢Gordon Linoff),以便其他人能够受益:

SELECT
         OT.TRADER_ID,
         OT.TRADER_NAME,
         OT.EXEC_BROKER,
         RANK() OVER (PARTITION BY OT.TRADER_ID ORDER BY 
                SUM(OT.TRADE_AMOUNT) DESC) AS CCP_RANK,
         SUM(OT.TRADE_AMOUNT) AS TRADED_AMT_WITH_CCP,
         SUM(SUM(OT.TRADE_AMOUNT)) OVER (PARTITION BY OT.TRADER_ID) AS 
         VALUE_OF_TOTAL_TRADES,
         COUNT(*) OVER (PARTITION BY OT.TRADER_ID) AS NUM_OF_CCP_USED,
         SUM(COUNT(OT.TRADE_ID)) OVER (PARTITION BY OT.TRADER_ID) AS 
         TOTAL_TRADES
    
    FROM dbo.ORDERS_TRADES OT
    
    GROUP BY OT.TRADER_ID, OT.TRADER_NAME, OT.EXEC_BROKER

对术语做一些假设,这里有一个解决方案,它不使用任何太花哨的东西,因此易于维护,尽管它不是最有效的:


create table trades
(
    TRADER_ID varchar(10), 
    TRADER_NAME varchar(20), 
    CCP char(4), 
    TRADED_AMT decimal(10,2), 
    TRADE_ID varchar(10) primary key
);

insert trades
values
    ('ABC123', 'Jules Winnfield', 'GOLD', 10000 , 'ASDADAD'),
    ('XDA241', 'Jimmie Dimmick ', 'GOLD', 12000 , 'ASSVASD'),
    ('ADC123', 'Vincent Vega   ', 'BARC', 10000 , 'ZXCZCX'),
    ('ABC123', 'Jules Winnfield', 'BARC', 15000 , 'ASSXCQA'),
    ('ADC123', 'Vincent Vega   ', 'CRED', 250000, 'RFAQQA'),
    ('ABC123', 'Jules Winnfield', 'CRED', 5000  , 'ASDQ23A'),
    ('ABC123', 'Jules Winnfield', 'GOLD', 5000  , 'AVBDQ3A');

with trader_totals as 
(
    select   trader_id,
             distinct_ccps = count(distinct CCP),
             total_amt = sum(traded_amt),
             total_count = count(*)
    from     trades
    group by trader_id
)
select      trader_id               = tr.trader_id,
            trader_name             = trader_name,
            distinct_CCP_count      = tt.distinct_ccps,
            CCP                     = tr.CCP,
            this_CCP_traded_amt     = sum(traded_amt),
            total_traded_amt        = tt.total_amt,
            this_CCP_traded_count   = count(*),
            total_traded_count      = tt.total_count

from        trades          tr
join        trader_totals   tt on tt.trader_id = tr.trader_id
group by    tr.trader_id,
            tr.trader_name,
            tr.CCP,
            tt.distinct_ccps,
            tt.total_amt,
            tt.total_count

对术语做一些假设,这里有一个解决方案,它不使用任何太花哨的东西,因此易于维护,尽管它不是最有效的:


create table trades
(
    TRADER_ID varchar(10), 
    TRADER_NAME varchar(20), 
    CCP char(4), 
    TRADED_AMT decimal(10,2), 
    TRADE_ID varchar(10) primary key
);

insert trades
values
    ('ABC123', 'Jules Winnfield', 'GOLD', 10000 , 'ASDADAD'),
    ('XDA241', 'Jimmie Dimmick ', 'GOLD', 12000 , 'ASSVASD'),
    ('ADC123', 'Vincent Vega   ', 'BARC', 10000 , 'ZXCZCX'),
    ('ABC123', 'Jules Winnfield', 'BARC', 15000 , 'ASSXCQA'),
    ('ADC123', 'Vincent Vega   ', 'CRED', 250000, 'RFAQQA'),
    ('ABC123', 'Jules Winnfield', 'CRED', 5000  , 'ASDQ23A'),
    ('ABC123', 'Jules Winnfield', 'GOLD', 5000  , 'AVBDQ3A');

with trader_totals as 
(
    select   trader_id,
             distinct_ccps = count(distinct CCP),
             total_amt = sum(traded_amt),
             total_count = count(*)
    from     trades
    group by trader_id
)
select      trader_id               = tr.trader_id,
            trader_name             = trader_name,
            distinct_CCP_count      = tt.distinct_ccps,
            CCP                     = tr.CCP,
            this_CCP_traded_amt     = sum(traded_amt),
            total_traded_amt        = tt.total_amt,
            this_CCP_traded_count   = count(*),
            total_traded_count      = tt.total_count

from        trades          tr
join        trader_totals   tt on tt.trader_id = tr.trader_id
group by    tr.trader_id,
            tr.trader_name,
            tr.CCP,
            tt.distinct_ccps,
            tt.total_amt,
            tt.total_count
你似乎想要:

SELECT OT.TRADER_ID, OT.TRADER_NAME, OT.CCP,
       COUNT(*) OVER (PARTITION BY OT.TRADER_ID) as NUM_CCP,
       SUM(OT.TRADED_AMT) AS TRADED_AMT_WITH_CCP,
       SUM(SUM(OT.TRADED_AMT)) OVER (PARTITION BY OT.TRADER_ID) AS VALUE_OF_TOTAL_TRADES,
       COUNT(OT.TRADE_ID) AS CCP_TRADES,
       SUM(COUNT(OT.TRADE_ID)) OVER (PARTITION BY OT.TRADER_ID) AS TOTAL_TRADES
FROM ORDERS_TRADES OT
GROUP BY OT.TRADER_ID, OT.TRADER_NAME, OT.CCP;
我不确定你的查询与你想要的结果有什么关系。这些专栏与您的提问几乎没有关系

是一把小提琴。

您似乎想要:

SELECT OT.TRADER_ID, OT.TRADER_NAME, OT.CCP,
       COUNT(*) OVER (PARTITION BY OT.TRADER_ID) as NUM_CCP,
       SUM(OT.TRADED_AMT) AS TRADED_AMT_WITH_CCP,
       SUM(SUM(OT.TRADED_AMT)) OVER (PARTITION BY OT.TRADER_ID) AS VALUE_OF_TOTAL_TRADES,
       COUNT(OT.TRADE_ID) AS CCP_TRADES,
       SUM(COUNT(OT.TRADE_ID)) OVER (PARTITION BY OT.TRADER_ID) AS TOTAL_TRADES
FROM ORDERS_TRADES OT
GROUP BY OT.TRADER_ID, OT.TRADER_NAME, OT.CCP;
我不确定你的查询与你想要的结果有什么关系。这些专栏与您的提问几乎没有关系


这个问题很难理解,因为你一直在变换术语。例如,您谈到“交易对手”,但没有“交易对手”列。你说的是“小计”,但没有“小计”栏。您的查询引用了“交易金额”,但没有“交易金额”列。您的查询引用了“exec_broker”,但没有“exec_broker”列。Hi-抱歉显然不是这样做的意思。CCP=交易对手,也称为执行经纪人。实际上,我从未使用过“小计”术语;我想这是在编辑我的标题时发生的。我所指的“小计”是与CCP的交易,以及上述我期望产出中的总交易。交易金额与交易金额相同,但我已在问题中对此进行了修正以澄清。谢谢这个问题很难理解,因为你一直在变换术语。例如,您谈到“交易对手”,但没有“交易对手”列。你说的是“小计”,但没有“小计”栏。您的查询引用了“交易金额”,但没有“交易金额”列。您的查询引用了“exec_broker”,但没有“exec_broker”列。Hi-抱歉显然不是这样做的意思。CCP=交易对手,也称为执行经纪人。实际上,我从未使用过“小计”术语;我想这是在编辑我的标题时发生的。我所指的“小计”是与CCP的交易,以及上述我期望产出中的总交易。交易金额与交易金额相同,但我已在问题中对此进行了修正以澄清。谢谢你的代码是完美的,我能够适应它来解决我的问题-非常感谢!我还使用RANK()按每个交易对手的交易价值按desc顺序对最终结果进行排序。再次感谢!你的代码是完美的,我能够适应它来解决我的问题-非常感谢!我还使用RANK()按每个交易对手的交易价值按desc顺序对最终结果进行排序。再次感谢!