【问题标题】:Get the Sum of a column grouped by another column then grouped into another获取由另一列分组的列的总和,然后分组到另一列
【发布时间】:2012-06-27 22:11:06
【问题描述】:

我已经尝试了一段时间来解决这个问题,但我缺乏更高级的 SQL 技能让我望而却步。

Executions(TradeDate, Symbol, Side, Price, Under, Account)

TEMP DATA:
2012-06-20, AAPL 120716C00600000, BUY, 3.25, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, SELL, 3.30, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, BUY, 3.25, AAPL, XYZ123
2012-06-20, AAPL 120716C00600000, SELL, 3.30, AAPL, XYZ123
2012-06-20, GRPN 120716C00027000, BUY, 2.25, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, SELL, 2.30, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, SELL, 2.30, GRPN, XYZ123
2012-06-20, GRPN 120716C00027000, BUY, 2.25, GRPN, XYZ123


-UNDER----Side(Buy)----Side(Sell)
 AAPL      6.50         6.60
 GRPN      4.50         4.60

如您所见,我正在尝试获取每边的价格总和,然后按下方分组。

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2


    【解决方案1】:

    使用GROUP BY 分组Under 列和CASESUM 关联以获得所需的结果:

    SELECT e.Under,
           SUM(case when e.Side = 'BUY' them e.Price else 0 end) as 'Side(Buy)',
           SUM(case when e.Side = 'SELL' them e.Price else 0 end) as 'Side(Sell)'
    FROM Executions e
    GROUP BY e.Under
    

    【讨论】:

    • 谢谢,感谢您的帮助
    • 是的,我必须等 9 分钟才可以。
    【解决方案2】:

    您可以为此使用PIVOT。 (见SQL Fiddle for Demo

    select *
    from 
    (
        select under, price, side
        from executions
    ) x
    PIVOT
    (
        sum(price)
        for side in ([BUY], [SELL])
    ) p
    

    【讨论】:

    • 使用 Case 和 Pivot 哪个更有效?
    • 我只是查看了两者的执行计划,因为只有两列,所以对于这个查询,它们看起来大致相同。对于这些类型的查询,我通常使用PIVOT,因为您可以使它们动态化,因此您不必为每一列编写代码。
    【解决方案3】:
     select Symbol, sum(case when side = 'BUY' THEN Price else 0 END) as [Side(Buy)], sum(case when side = 'SELL' THEN Price else 0 END) as [Side(Sell)] group by Symbol
    

    【讨论】:

      【解决方案4】:

      这是一种方法:

      SELECT e.under
           , SUM(CASE WHEN e.side = 'BUY'  THEN e.price ELSE NULL END) AS [Side(Buy)]
           , SUM(CASE WHEN e.side = 'SELL' THEN e.price ELSE NULL END) AS [Side(Sell)]
        FROM Executions e
       GROUP BY e.under
      

      这里的“技巧”是使用 CASE 表达式仅返回特定侧值的价格。 (注意:正如有人不可避免地指出的那样,ELSE NULL 是隐含的,可以省略。)

      这不是唯一的方法。但是,如果您还需要获取每个总和中包含的行的“计数”以及所有行的计数,那么这是一种非常灵活的方法,效果很好。为了说明正在使用的这种方法:

       SELECT e.under
           , SUM(CASE WHEN e.side = 'BUY'  THEN e.price ELSE NULL END) AS [SUM_Side(Buy)]
           , SUM(CASE WHEN e.side = 'BUY'  THEN 1       ELSE 0    END) AS [COUNT_Side(Buy)]
           , SUM(CASE WHEN e.side = 'SELL' THEN e.price ELSE NULL END) AS [SUM_Side(Sell)]
           , SUM(CASE WHEN e.side = 'SELL' THEN 1       ELSE 0    END) AS [COUNT_Side(Sell)]
           , SUM(CASE WHEN e.side IN ('BUY','SELL') THEN 1 ELSE 0 END) AS [COUNT_(Buy+Sell)]
        FROM Executions e
       GROUP BY e.under
      

      这种方法通常具有非常可预测的性能,并且它要求源数据集只被引用一次(在这种情况下,是一个简单的表引用)

      这种方法几乎适用于所有关系数据库。 (Oracle、SQL Server、MySQL、Teradata、DB2、...)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 2020-12-06
        • 1970-01-01
        • 2016-06-11
        • 2016-11-07
        相关资源
        最近更新 更多