如何计算GROUP BY SQL中的特定行

时间:2017-12-20 21:56:51

标签: mysql sql

我有一个SQL查询,它将两个类似的查询连接到一个临时表中。然后,我从该单个临时表构建结果集。

最终结果集的一部分应包括哪些行是“Equities”和“Options”。为了解决这个问题,我添加了硬编码列。

粗略/简化的ERD如下所示: enter image description here

Equity在EquityType列中有一个硬编码1,而Options在OptionType列中有一个硬编码1。顺便说一句,TH.Type列还包含唯一值来区分行与Equity或Option(值将是'Equity'或'Option')。

我觉得我的解决方案充其量只是一个黑客攻击;并且必须有更好的选择。

我的sql适用于MySql,但我不相信答案是特定于数据库的。这是sql:

-- step 1 get equities
CREATE TEMPORARY TABLE IF NOT EXISTS PositionDetails AS
    (
    SELECT TH.Id,
        TH.Symbol,
        TH.TransactionDate,
        TH.Type,
        1 AS 'EquityType',
        0 AS 'OptionType',
        TH.State,
        TH.Position,
        TE.Shares AS Units,
        TE.SharePrice AS UnitPrice,
        TE.Commission,
        TE.Action,
        '' AS 'Data',
        0 AS StrikePrice,
        '' AS 'ExtendedType'
    FROM TradeHeader TH 
    LEFT JOIN TradeEquity TE ON TE.TradeId = TH.Id    
    WHERE TH.Type = 'Equity' AND TH.State = 'Open'
    );

-- step 2 get options
CREATE TEMPORARY TABLE IF NOT EXISTS PositionDetails AS
    (
    SELECT TH.Id,
        TH.Symbol,
        TH.TransactionDate,
        TH.Type,
        0 AS 'EquityType',
        1 AS 'OptionType',        
        TH.State,
        TH.Position,
        TOP.Contracts AS Units,
        TOP.UnitPrice,
        TOP.Commission,
        TOP.Action,
        TOP.ExpirationDate AS 'Data',
        TOP.StrikePrice AS StrikePrice,
        TOP.OptionType AS 'ExtendedType'
    FROM TradeHeader TH
    LEFT JOIN TradeOption TOP ON TOP.TradeId = TH.Id
    WHERE TH.Type = 'Option' AND TH.State = 'Open'
    );

-- step 3 summarize the data    
SELECT 
    PD.Symbol    
  , MIN(PD.TransactionDate) AS FirstTrans
  , MAX(PD.TransactionDate) AS MostRecentTrans
  , SUM((PD.Units * PD.UnitPrice) + PD.Commission) AS Cost
  , COUNT(PD.Symbol) AS Transactions
  , SUM(PD.EquityType) As EquityTrades
  , Sum(PD.OptionType) AS OptionTrades
FROM PositionDetails PD 
GROUP BY PD.Symbol
ORDER BY PD.Symbol;

我的问题是:如果没有我在SQL语句第1步和第2步中添加的硬编码列,我如何在步骤3中获取EquityTrades的值。

例如,这些列:

0 AS 'EquityType',
1 AS 'OptionType', 

日Thnx, 马特

修改 下面更新了SQL:

CREATE TEMPORARY TABLE IF NOT EXISTS PositionDetails AS
    (
    SELECT 
        TH.Id
      , TH.Symbol
      , TH.TransactionDate
      , TH.Type
      , TH.State
      , TH.Position
      , TE.Shares AS Units
      , TE.SharePrice AS UnitPrice
      , TE.Commission
      , TE.Action
      , '' AS 'Data'
      , 0 AS StrikePrice
      , '' AS 'ExtendedType'
    FROM TradeHeader TH 
    LEFT JOIN TradeEquity TE ON TE.TradeId = TH.Id    
    WHERE TH.Type = 'Equity' AND TH.State = 'Open'
    );

INSERT INTO PositionDetails 

    SELECT 
        TH.Id
      , TH.Symbol
      , TH.TransactionDate
      , TH.Type
      , TH.State
      , TH.Position
      , TOP.Contracts AS Units
      , TOP.UnitPrice
      , TOP.Commission
      , TOP.Action
      , TOP.ExpirationDate AS 'Data'
      , TOP.StrikePrice AS StrikePrice
      , TOP.OptionType AS 'ExtendedType'    
    FROM TradeHeader TH
    LEFT JOIN TradeOption TOP ON TOP.TradeId = TH.Id
    WHERE TH.Type = 'Option' AND TH.State = 'Open'
    ;


SELECT 
    PD.Symbol    
  , MIN(PD.TransactionDate) AS FirstTrans
  , MAX(PD.TransactionDate) AS MostRecentTrans
  , SUM((PD.Units * PD.UnitPrice) + PD.Commission) AS Cost
  , COUNT(PD.Symbol) AS Transactions
  , SUM(PD.Type = 'Equity') As EquityTrades
  , Sum(PD.Type <> 'Equity') AS OptionTrades
FROM PositionDetails PD 
GROUP BY PD.Symbol
ORDER BY PD.Symbol;

2 个答案:

答案 0 :(得分:1)

要聚合联合,这是基本格式:

SELECT ..., SUM(subU.someValueField)
FROM (
   ... 
   UNION 
   ...
) AS subU
GROUP BY subU.Xfield, subU.Yfield

答案 1 :(得分:1)

不要使用EquityTypeOptionType列,只需使用Type列。

SUM(type = 'Equity') AS EquityTrades,
SUM(type = 'Option') AS OptionTrades

您的第二个CREATE TEMPORARY TABLE查询应该是INSERT INTO PositionDetails,因为该表已存在于第一个查询中。

CREATE TEMPORARY TABLE PositionDetails AS
    (
    SELECT TH.Id,
        TH.Symbol,
        TH.TransactionDate,
        TH.Type,
        TH.State,
        TH.Position,
        TE.Shares AS Units,
        TE.SharePrice AS UnitPrice,
        TE.Commission,
        TE.Action,
        '' AS 'Data',
        0 AS StrikePrice,
        '' AS 'ExtendedType'
    FROM TradeHeader TH 
    LEFT JOIN TradeEquity TE ON TE.TradeId = TH.Id    
    WHERE TH.Type = 'Equity' AND TH.State = 'Open'
    );

INSERT INTO PositionDetails
SELECT TH.Id,
    TH.Symbol,
    TH.TransactionDate,
    TH.Type,
    TH.State,
    TH.Position,
    TOP.Contracts AS Units,
    TOP.UnitPrice,
    TOP.Commission,
    TOP.Action,
    TOP.ExpirationDate AS 'Data',
    TOP.StrikePrice AS StrikePrice,
    TOP.OptionType AS 'ExtendedType'
FROM TradeHeader TH
LEFT JOIN TradeOption TOP ON TOP.TradeId = TH.Id
WHERE TH.Type = 'Option' AND TH.State = 'Open';

SELECT 
    PD.Symbol    
  , MIN(PD.TransactionDate) AS FirstTrans
  , MAX(PD.TransactionDate) AS MostRecentTrans
  , SUM((PD.Units * PD.UnitPrice) + PD.Commission) AS Cost
  , COUNT(*) AS Transactions
  , SUM(PD.Type = 'Equity') As EquityTrades
  , Sum(PD.Type = 'Option') AS OptionTrades
FROM PositionDetails PD 
GROUP BY PD.Symbol
ORDER BY PD.Symbol;