连接最大N组:获取错误的最大/最小值

时间:2016-04-16 00:07:58

标签: sql-server greatest-n-per-group

可悲的是,流行的“Greatest-N-Per-Group”查询的另一个变种,但它一直踢我的屁股,我真的可以使用一些清晰度(尽可能简化问题):

我有两张桌子:

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

我正在尝试制定一个查询,显示每个项目的清单ID,项目ID,项目名称,条件和最高价格在给定条件下

即。给定

ItemID    ItemName
ITEM001   Lg Widget
ITEM002   Sm Widget

和物品:

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

我期待:

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

我正在尝试这个:

:empty

不幸的是,这并没有产生预期的结果:它似乎偶尔会在所有条件下返回商品的最高价格,而不是在给定条件下商品的最高价格

想法?

1 个答案:

答案 0 :(得分:0)

我并不完全清楚您的数据是如何相关的,或者您需要如何过滤。

我要么这样做:

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

或者这样:

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

如果您只想要一个ItemID,即使您有价格关系,也可以将DENSE_RANK()替换为ROW_NUMBER()。但是,除非您在ORDER BY子句中向OVER()添加关键字段,否则结果将不具有确定性。