T-SQL Назначение MAX в этой группе по запросу

Я столкнулся с некоторыми ранее существующими SQL, с которыми мне трудно справляться.

SELECT
    MAX(I.Symbol) Symbol
,   MAX(I.Ticker) CUSIP
,   MAX(I.Name) Name
,   SUM(H.Quantity) TotalQuantity
,   SUM(H.MarketValue) TotalMarketValue
,   MAX(H.PriceLC) Price
,   MAX(I.CategoryCode5) BUY_SELL
,   MAX(I.EquivFactor1) PriceTgt
,   MAX(P.LastPrice) CurrPrice
,   MAX(I.AssetClass) Target
,   MAX(I.Industry) Industry
,   MAX(I.CategoryCode1) Risk
FROM
    HOLDINGS_SECURE H
,   INVESTMENTS I
,   PRICE P
WHERE
    H.Symbol = I.Symbol
    AND I.Product = 'stock'
    AND H.Quantity > 0
    AND I.CategoryCode5 NOT IN ('X', '')
    AND H.Symbol = P.Symbol
GROUP BY
    I.Symbol

Символ, Тикер, Имя, CategoryCode5, Класс Assest, Промышленность и CategoryCode1 - все поля varchar. Остальные поля - десятичные.

Мое лучшее обоснованное предположение заключается в том, что как-то макс используется, чтобы избежать нескольких столбцов группировки, но как это может вернуть правильные результаты?

Таблицы Реляционная диаграмма

6 голосов | спросил W.Jackson 7 Jpm1000000pmMon, 07 Jan 2013 21:06:35 +040013 2013, 21:06:35

2 ответа


8

Вы говорите: «Моя лучшая образованная догадка заключается в том, что как-то макс используется, чтобы избежать нескольких столбцов группировки»

Это правильно.

, а затем: "... но как это может вернуть правильные результаты?"

Он возвращает правильные результаты, потому что Symbol является первичным ключом как в Investments и таблицы Price. Поэтому любая агрегатная функция над P.column или I.column объединяет идентичные значения. И MAX(c), когда c есть 2, 2, 2 or 2, конечно, 2.

Может ли запрос быть написан каким-то другим, возможно, без всех этих агрегатов? Да, см. Связанный с этим вопрос: Почему Подстановочные знаки в операторах GROUP BY не работают?

Это должно быть довольно длинное предложение GROUP BY или иметь скопления, перемещенные в подзапрос, только с Holdings_Secure (где Symbol не является основным ключом), а затем присоединился к двум другим:

SELECT
    I.Symbol Symbol
,   I.Ticker CUSIP
,   I.Name Name

,   H.TotalQuantity
,   H.TotalMarketValue
,   H.Price

,   I.CategoryCode5 BUY_SELL
,   I.EquivFactor1 PriceTgt
,   P.LastPrice CurrPrice
,   I.AssetClass Target
,   I.Industry Industry
,   I.CategoryCode1 Risk
FROM
    ( SELECT 
          SUM(Quantity) TotalQuantity
      ,   SUM(MarketValue) TotalMarketValue
      ,   MAX(PriceLC) Price
      ,   Symbol
      FROM
          HOLDINGS_SECURE
      WHERE
          Quantity > 0
      GROUP BY
          Symbol
    ) H
  JOIN
    INVESTMENTS I
      ON H.Symbol = I.Symbol
  JOIN
    PRICE P
      ON H.Symbol = P.Symbol
WHERE
        I.Product = 'stock'
    AND I.CategoryCode5 NOT IN ('X', '') ;
ответил ypercubeᵀᴹ 7 Jpm1000000pmMon, 07 Jan 2013 23:43:54 +040013 2013, 23:43:54
4

Может быть, агрегаты лучше подходят в подзапросе и имеют больше смысла, когда это подзапрос, который позже присоединился к другой таблице INVESTMENTS и PRICE - см. ниже.

В этом случае вы могли бы сказать, что «причина» для этого может быть:

  • неопытность разработчика w /SQL
  • опыт разработчика, полученный на платформе SQL, который не поддерживает подзапросы таблицы
  • стиль разработчика

Может случиться так, что некоторые данные в таблицах нормализованы неправильно или что-то подобное, как предложено в других комментариях, или это может быть просто неправильно.

Вот догадка о том, как возможно его можно было бы переписать более аккуратно с помощью подзапроса, а затем другой запрос, который может помочь проанализировать данные для аномалий, если это окажется необходимым.

возможно переписать:

SELECT
    I.Symbol Symbol
,   I.Ticker CUSIP
,   I.Name Name
,   H.Quantity TotalQuantity
,   H.MarketValue TotalMarketValue
,   H.PriceLC Price
,   I.CategoryCode5 BUY_SELL
,   I.EquivFactor1 PriceTgt
,   P.LastPrice CurrPrice
,   I.AssetClass Target
,   I.Industry Industry
,   I.CategoryCode1 Risk
FROM (
    --begin holdings_secure_aggregated
    SELECT
    Symbol,
    SUM(Quantity) TotalQuantity,
    SUM(MarketValue) TotalMarketValue,
    MAX(PriceLC) PriceLC
    FROM HOLDINGS_SECURE
    WHERE Quantity > 0
    GROUP BY Symbol
) H, --end holdings_secure_aggregated
INVESTMENTS I, PRICE P
WHERE
    H.Symbol = I.Symbol
    AND I.Product = 'stock'
    AND I.CategoryCode5 NOT IN ('X', '')
    AND H.Symbol = P.Symbol
GROUP BY I.Symbol;

Вы можете использовать что-то некрасивое, как это, чтобы увидеть, какие значения I.Symbol - если они есть - возвращают более одного значения из столбцов, которые агрегируются с использованием MAX, и точно видеть, что представляют собой эти индивидуальные значения.

SELECT
    I.Symbol Symbol
,   I.Ticker CUSIP
,   I.Name Name
,   H.Quantity TotalQuantity
,   H.MarketValue TotalMarketValue
,   H.PriceLC Price
,   I.CategoryCode5 BUY_SELL
,   I.EquivFactor1 PriceTgt
,   P.LastPrice CurrPrice
,   I.AssetClass Target
,   I.Industry Industry
,   I.CategoryCode1 Risk
FROM
    HOLDINGS_SECURE H
,   INVESTMENTS I
,   PRICE P
WHERE
    H.Symbol = I.Symbol
    AND I.Product = 'stock'
    AND H.Quantity > 0
    AND I.CategoryCode5 NOT IN ('X', '')
    AND H.Symbol = P.Symbol
    AND EXISTS (
        SELECT I.Symbol
        FROM
            HOLDINGS_SECURE H
        ,   INVESTMENTS I
        ,   PRICE P
        WHERE
            H.Symbol = I.Symbol
            AND I.Product = 'stock'
            AND H.Quantity > 0
            AND I.CategoryCode5 NOT IN ('X', '')
            AND H.Symbol = P.Symbol
        GROUP BY
            I.Symbol
        HAVING (
            COUNT(DISTINCT I.Ticker)
            + COUNT(DISTINCT I.Name)
            + COUNT(DISTINCT H.PriceLC)
            + COUNT(DISTINCT I.CategoryCode5)
            + COUNT(DISTINCT I.EquivFactor1)
            + COUNT(DISTINCT P.LastPrice)
            + COUNT(DISTINCT I.AssetClass)
            + COUNT(DISTINCT I.Industry)
            + COUNT(DISTINCT I.CategoryCode1)
        )
        > 0
    );
ответил JM Hicks 7 Jpm1000000pmMon, 07 Jan 2013 21:55:58 +040013 2013, 21:55:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132