2016-04-16 2 views
0

Leider eine andere Variante der beliebten "Greatest-N-Per-Group" Abfrage, aber es hat meinen Hintern getreten und ich könnte wirklich Klarheit gebrauchen (Problem vereinfacht) so viel wie möglich):Größte N pro Gruppe mit Joins: Falsche Max/Min Werte erhalten

ich zwei Tabellen haben:

Items 
----- 
ItemID 
ProductName 


Inventory 
--------- 
InventoryID 
ItemID 
Condition 
Price 

und ich versuche, eine Abfrage zu formulieren, die zeigt die InventoryID, ItemID, ItemName, Zustand und Maxpreise für jeden Artikel In einer gegebenen Bedingung

dh gegeben

Inventory 
--------- 
InventoryID ItemID Condition Price 
INV123  ITEM001 NEW   $3.99 
INV001  ITEM001 NEW   $3.79 
INV031  ITEM001 USED  $1.23 
INV234  ITEM001 USED  $1.99 

und Artikel:

ItemID ItemName 
ITEM001 Lg Widget 
ITEM002 Sm Widget 

ich erwarten würde:

ItemID ItemName Condition MaxPrice MaxPriceInventoryID 
ITEM001 Lg Widget NEW  $3.99 INV123 
ITEM001 Lg Widget USED  $1.99 INV234 

Ich versuche dies:

SELECT 
    ItemID, ItemName, b.condition, b.maxprice, 
    InventoryID as MaxPriceInventoryID 
FROM 
    Items I join inventory v On i.ItemID= v.ItemID 
    join (
     select inventory.ItemID, max(Price) as MaxPrice, condition 
      from inventory join Items on inventory.ItemID = Items.ItemID 
      group by inventory.ItemID, condition) as b 
    on b.ItemID = v.ItemID and b.MaxPrice = v.Price 
ORDER BY 
    ItemName, Condition 

Leider doesn diese‘ t das gewünschte ergebnis geben: es scheint sporadisch zu sein Max-Preis für den Artikel über alle Bedingungen, nicht Max-Preis für den Artikel in einer bestimmten Bedingung drehen

Ideen?

Antwort

0

Es ist mir nicht ganz klar, wie genau Ihre Daten zusammenhängen oder wie Sie filtern müssen.

würde ich es entweder so:

SELECT ii.ItemID 
    ,ii.ItemName 
    ,ii.Condition 
    ,ii.Price AS MaxPrice 
    ,ii.MaxPriceInventoryID 
FROM (
    SELECT i.ItemID 
     ,i.ItemName 
     ,i.ProductName 
     ,v.InventoryID 
     ,v.Condition 
     ,v.Price 
     ,DENSE_RANK() OVER (PARTITION BY v.ItemID, v.Condition ORDER BY v.Price DESC) AS R 
    FROM Items i 
    INNER JOIN Inventory v 
     ON i.ItemID = v.ItemID 
    WHERE 1 = 1 /* Place your filtering conditionals here */ 
    ) AS ii 
WHERE ii.R = 1 
ORDER BY ii.ItemName 
    ,ii.Condition 

Oder so:

SELECT i.ItemID 
    ,i.ItemName 
    ,vv.Condition 
    ,vv.Price AS MaxPrice 
    ,vv.MaxPriceInventoryID 
FROM Items i 
INNER JOIN (
    SELECT v.ItemID 
     ,v.InventoryID 
     ,v.Condition 
     ,v.Price 
     ,DENSE_RANK() OVER (PARTITION BY v.ItemID, v.Condition ORDER BY v.Price DESC) AS R 
    FROM Inventory v 
    WHERE 1 = 1 /* Place your filtering conditionals here */ 
    ) AS vv 
    ON i.ItemID = vv.ItemID 
WHERE vv.R = 1 
ORDER BY i.ItemName 
    ,vv.Condition 

Wenn Sie nur noch eine ItemID wünschen, wenn Sie Bindungen auf den Preis haben, dann können Sie DENSE_RANK() ersetzen mit ROW_NUMBER(). Wenn Sie jedoch kein Schlüsselfeld zu Ihrem ORDER BY in der OVER()-Klausel hinzufügen, wird das Ergebnis nicht deterministisch sein.

Verwandte Themen