2017-09-30 2 views
0

Nach SQL Return every row even if Null values muss ich die Zeilendaten auswählen, die mit MAX (contractPrice) verknüpft sind, wenn sie nach zwei Spalten gruppiert sind.SQL Zeilenwerte für MAX() erhalten, gruppiert nach 2 Spalten

Ich habe sqlfiddle.com/#!6/170043/2 eingerichtet, um zu demonstrieren, dass das Problem der Code unten ist, der Duplikate zurückgibt (siehe 5. und 6. Zeile der sqlifiddle-Ergebnisse), wenn der maximale Preis wiederholt wird.

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 

Antwort

1

Es gibt ein paar Dinge, die sehr verwirrend sind oder Klärung bedürfen hier:

  1. Ihr Tag ist Sql-Server, aber man hat uns mit einer Probe mit MySql
  2. Die Verwendung einer abgeleiteten Tabelle nicht scheint notwendig, in der Tat macht es ein bisschen verwirrend.

das gesagt ist, wenn Sie den MAX ContractPrice mit MAX ID wollen diese verschiedenen Wegen erreicht werden kann. Bitte beachten Sie auch, dass ich den Rest der Spalten nicht richtig aggregiert habe, was eine schlechte Übung ist. Wickeln Sie einfach den Rest der Spalten, die in einer MAX() nicht aggregiert oder gruppiert sind:

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 

Die andere Methode ist, wenn dies tatsächlich SQL-Server ist, können Sie ROW_NUMBER und eine abgeleitete Tabelle verwenden können:

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 
+0

1.) Leider mein Fehler auf sqlfiddle hier ist Link für SQL-Server http://sqlfiddle.com/#!6/170043/ 2 2.) Ich werde Ihren Code versuchen und beraten, danke. –

+0

Beachten Sie, dass Ihr erster Codeblock den Fehler auslöst: "Spalte 'contracts.UTCmatched' ist in der Auswahlliste ungültig, da sie weder in einer Aggregatfunktion noch in der GROUP BY-Klausel enthalten ist." und dass, selbst wenn die letzten drei Auswahlen entfernt werden, die MAX (ID), die zurückgegeben wird, der höchste ID-Wert ist (und nicht der ID-Wert, der dem höchsten Preis zugeordnet ist). –

+0

Ja, ich habe bemerkt, dass die Spalten richtig aggregiert werden müssen. Ich habe es aktualisiert, um zu reflektieren, was ich meine. Fahren Sie fort und führen Sie es erneut aus. – Simon

0

Ihre Anfrage kann durch simplifed und „korrigiert“:

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) 

Aber ich, was Sie noch Duplikate haben wird ... Ich denke, Ihre gesamte Abfrage Konzept falsch ist.

0

PS Ich kann Duplikate eliminieren durch Verwendung Row_Number() - pro Code unten:

 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 
Verwandte Themen