SQL获取MAX()的行值,按2列

时间:2017-09-30 22:15:39

标签: sql-server group-by max

SQL Return every row even if Null values开始,我需要在按两列分组时选择与MAX(contractPrice)相关联的行数据。

我已经设置了sqlfiddle.com/#!6/170043/2,以证明问题是下面的代码返回重复项(如果重复最高价格,则返回第7行和第6行的sqlfiddle结果)。

    SELECT
        t1.MeasurableID,
        t1.EntityID,
        t1.ContractPrice,
        ID,
        UTCMatched,
        NumberOfContracts,
        CurrencyCode
    FROM
        contracts AS t1
    INNER JOIN (
        SELECT
            MeasurableID,
            EntityID,
            MAX (contractprice) AS MAXprice
        FROM
            contracts
        WHERE
            MeasurableID IN (2017, 2018)
        AND CurrencyCode IN ('CAD', 'BTC')
        GROUP BY
            MeasurableID,
            EntityID
    ) t2 ON t1.MeasurableID = t2.MeasurableID
    AND t1.EntityID = t2.EntityID
    AND t1.ContractPrice = t2.MAXprice
    WHERE
        t1.MeasurableID IN (2017, 2018)
    AND t1.CurrencyCode IN ('CAD', 'BTC')
    ORDER BY
        MeasurableID,
        EntityID,
        UTCMatched

3 个答案:

答案 0 :(得分:1)

有一些事情令人困惑或需要澄清:

  1. 您的代码为Sql-Server,但您向我们提供了MySql
  2. 的示例
  3. 派生表的使用似乎没有必要,事实上它使它有点混乱。
  4. 话虽如此,如果你想要MAX ContractPrice及其MAX ID,可以通过多种方式完成。还请注意我没有正确地聚合其余的列,这是不好的做法。只需将未聚合或分组的其余列包装在MAX()中:

    SELECT 
        t1.MeasurableID,
        t1.EntityID,
        MAX(t1.contractprice) AS MAXprice,
        MAX(t2.ID) as ID,
        MAX(t2.UTCMatched) as UTCMatched,
        MAX(t2.NumberOfContracts) AS NumberOfContracts,
        MAX(t2.CurrencyCode) AS CurrencyCode
    
    FROM
        contracts t1
    LEFT JOIN contracts t2 ON t1.MeasurableID = t2.MeasurableID
                              AND
                              t1.EntityID = t2.EntityID
                              AND
                              t1.ContractPrice = t2.ContractPrice
    
    WHERE
        t1.MeasurableID IN (2017, 2018)
    AND t1.CurrencyCode IN ('CAD', 'BTC')
    GROUP BY
        t1.MeasurableID,
        t1.EntityID
    

    另一种方法是,如果这实际上是SQL-Server,您可以使用ROW_NUMBER和派生表:

    SELECT MeasurableID
           ,EntityID
           ,ContractPrice
           ,ID
           ,UTCMatched
           ,NumberOfContracts
           ,CurrencyCode
    FROM
    (SELECT *
            ,ROW_NUMBER() OVER(PARTITION BY EntityID ORDER BY ContractPrice, ID DESC ) rn
    FROM Contracts t1) t1
    WHERE t1.rn = 1
    

答案 1 :(得分:0)

您的查询可以通过简化和“更正”:

   SELECT
        t1.MeasurableID,
        t1.EntityID,
        t1.ContractPrice,
        t1.ID,
        t1.UTCMatched,
        t1.NumberOfContracts,
        t1.CurrencyCode
    FROM contracts AS t1
    INNER JOIN contracts AS T2 ON (t1.MeasurableID = t2.MeasurableID AND MeasurableID IN (2017, 2018) AND CurrencyCode IN ('CAD', 'BTC'))
    ORDER BY
        t1.MeasurableID,
        t1.EntityID,
        t1.ContractPrice,
        t1.ID,
        t1.UTCMatched,
        t1.NumberOfContracts,
        t1.CurrencyCode
    HAVING t1.ContractPrice = MAX(T2.contractprice)

但我认为你仍然会有重复......我认为你的整个查询概念都是错误的。

答案 2 :(得分:0)

P.S。我可以使用Row_Number()消除重复项 - 按下面的代码:

        SELECT MeasurableID
             ,EntityID
             ,ContractPrice
             ,ID AS HighTradeID
             ,UTCMatched AS HighTradeUTC
             ,NumberOfContracts AS HighTradeNumberOfContracts
             ,CurrencyCode AS HighTradeCurrency
FROM
        (SELECT *
                        ,ROW_NUMBER() OVER(PARTITION BY MeasurableID, EntityID ORDER BY ContractPrice DESC, ID DESC ) RowNumber
        FROM Contracts t1
            WHERE
                MeasurableID IN (2017, 2018)
            AND CurrencyCode IN ('CAD', 'BTC')
        ) AS InnerSelect

WHERE InnerSelect.RowNumber = 1