我有3个表项目,地点和股票。
Items
ItemId ItemName
444 Item-1
555 Item-2
666 Item-3
Locations
LocationId LocationName
12 Loc1
13 Loc2
14 Loc3
15 Loc4
17 Loc5
Stock
Id ItemId LocationId stock
1 444 12 2
2 444 13 15
3 555 14 20
4 666 15 14
5 666 17 12
我需要针对每件商品获取1条记录,这些商品的库存最高。 我想要像这样的结果。
Result Table
ItemName LocationName stock
Item-1 Loc2 15
Item-2 Loc3 20
Item-3 Loc4 14
目前我正在使用以下查询。
Select I.ItemName,L.LocationName,S.stock from Items I
inner join Stock S on
I.ItemId = S.ItemId
inner join Locations L on
S.LocationId = L.LocationId
答案 0 :(得分:0)
在ANSI-SQL-98中,您首先要从库存表中找出每个项目的最大库存水平,然后重新连接以查找整行中的信息。从那里开始加入将ID转换为名称等的正常情况
SELECT
*
FROM
(
SELECT itemId, MAX(stock) AS stock FROM stock GROUP BY itemId
)
max_stock
INNER JOIN
stock
ON stock.itemId = max_stock.itemId
AND stock.stock = max_stack.stock
INNER JOIN
locations
ON locations.LocationId = stock.LocationId
INNER JOIN
Items
ON items.ItemId = stock.ItemId
在ANSI-SQL-2003中,您可以获得ROW_NUMBER()
和RANK()
等窗口函数...
SELECT
*
FROM
(
SELECT
stock.*,
RANK() OVER (PARTITION BY itemId
ORDER BY stock DESC
)
AS stock_level_rank
FROM
stock
)
ranked_stock
INNER JOIN
locations
ON locations.LocationId = ranked_stock.LocationId
INNER JOIN
Items
ON items.ItemId = ranked_stock.ItemId
WHERE
ranked_stock.stock_level_rank = 1
RANK()
的一个功能是可以将多行绑定到第一位。所以你不能总是每件商品获得一排。但是,如果两个地点的库存水平完全相同,那么它们都不应该被退回吗?这取决于您的要求。
如果 必须 只有一行,那么最好选择其他列/表达式,以便每次确定性地返回相同的结果。
ROW_NUMBER() OVER (PARTITION BY itemId
ORDER BY stock DESC,
id DESC
)
AS stock_level_rank
在这种情况下,id
更高的行会使行更多"优先"在领带的情况下选择的那个。这没有任何意义 真的 ,但至少你总是得到相同输入的相同结果。
答案 1 :(得分:0)
with cte as
( select itemID, locationID, stock
, row_number() over (partition by itemID order by stock desc) as rn
from stock
)
select *
from cte
join items i
on i.itemID = cte.itemID
and cte.rn = 1
join locations l
on l.LocationId = cte.LocationId