Как подсчитать конкретные строки в GROUP BY SQL

0

У меня есть SQL-запрос, который объединяет два похожих запроса в одну временную таблицу. Затем я создаю результирующий набор из этой единственной временной таблицы.

Часть окончательного набора результатов должна включать в себя подсчет строк: "Акции" и "Параметры". Чтобы решить эту проблему, я добавил строковые кодированные столбцы.

Грубая/упрощенная ERD выглядит так: Изображение 174551

Акции имеют жестко закодированный 1 в столбце EquityType, а опции имеют жесткую кодировку 1 в столбце OptionType. Кстати, столбец 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;

Мой вопрос: как я могу получить значения для EquityTrades на шаге 3, без жесткокодированных столбцов, которые я добавил в своих SQL-операциях, шаг 1 и шаг 2.

например, эти столбцы:

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

Тинкс, Мэтт

EDIT Обновлен 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 ответа

1
Лучший ответ

Вместо использования EquityType и OptionType просто используйте столбец " 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;
  • 0
    С INSERT INTO я должен указать столбцы? Документация выглядит так, что столбцы являются необязательными, но когда столбцы не указаны, возникает ошибка SQL: Код ошибки: 1136. Число столбцов не соответствует количеству значений в строке 1. Возможно, я неправильно читаю документацию.
  • 0
    Если вы не указываете столбцы, у вас должны быть значения для всех столбцов, и они должны быть в том же порядке, что и при создании таблицы.
Показать ещё 3 комментария
1

Для объединения объединения это основной формат:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню