我们为商店中的产品提供了此表格,其价值如下:
Id Name PartNumber Param1 Param2 Param3 Stock Active
-- --------- ---------- ------ ------ ------ ----- ------
1 BoxA1 10000 20 A B 4 1
2 BoxA1 10000.a 20 A B 309 1
3 CabinetZ2 30000 40 B C 0 0
4 CabinetZ2 30000.b 40 B C 1098 1
5 BoxA1 10000.c 20 A B 15 1
如您所见,有些产品具有相同的名称和参数,但ID和部件号不同。
Id为1,2和5的产品具有相同的名称和参数值。
我们需要根据库存禁用相同的param产品,因此我们只有具有相同参数的产品库存更活跃的产品。
结果应该是这样的:
Id Name PartNumber Param1 Param2 Param3 Stock Active
-- --------- ---------- ------ ------ ------ ----- ------
1 BoxA1 10000 20 A B 4 0 <- Not active
2 BoxA1 10000.a 20 A B 309 1 <- Active
3 CabinetZ2 30000 40 B C 0 0
4 CabinetZ2 30000.b 40 B C 1098 1
5 BoxA1 10000.c 20 A B 15 0 <- Not active
此过程是必需的,因为我们每天都会多次从外部来源(网络服务)接收库存数量,并且在每次库存更新后,我们需要评估哪些应该保持活动状态。
我们此时所做的工作正常但效果不佳的是使用执行以下操作的存储过程:
DECLARE product_list CURSOR READ_ONLY FORWARD_ONLY LOCAL FOR
SELECT Id, Name, PartNumber, Param1, Param2, Param3, Stock
FROM Products
ORDER BY Name, Param1, Param2, Param3, Stock DESC
OPEN product_list
FETCH NEXT FROM product_list INTO @OldId, @OldName, @OldPartNumber, @OldParam1, @OldParam2, @OldParam3, @OldStock
WHILE @@FETCH_STATUS <> -1
BEGIN
(Compare all rows and perform updates to disable the ones with less stock)
FETCH NEXT FROM product_list INTO @OldId, @OldName, @OldPartNumber, @OldParam1, @OldParam2, @OldParam3, @OldStock
END
CLOSE product_list
使用OVER(PARTITION BY)找到这种类型的查询,我们非常接近于提高效率的目标:
SELECT Id, Name, PartNumber, Param1, Param2, Param3, Stock, Active,
ROW_NUMBER() OVER (PARTITION BY Name, Param1, Param2, Param3 ORDER BY stock DESC) AS Items
FROM Products
具有以下结果:
Id Name PartNumber Param1 Param2 Param3 Stock Items
-- --------- ---------- ------ ------ ------ ----- ------
1 BoxA1 10000 20 A B 4 3
3 CabinetZ2 30000 40 B C 0 2
问题在于我们找到了第一个Id,而不是具有更多库存的Id。
我们期待这样的结果,但找不到修复此查询或解决方法的方法:
Id Name PartNumber Param1 Param2 Param3 Stock Items
-- --------- ---------- ------ ------ ------ ----- ------
2 BoxA1 10000.a 20 A B 309 3
4 CabinetZ2 30000.b 40 B C 1098 2
答案 0 :(得分:0)
WITH t AS (SELECT ROW_NUMBER() OVER (PARTITION BY Name, Param1, Param2, Param3 ORDER BY stock DESC) i,* FROM Products)
UPDATE t
SET Active = CASE i WHEN 1 THEN 1 ELSE 0 END
你的问题中存在一个含糊不清的问题:如果两个ID在库存中具有相同的#,它们是活动的,还是只有一个?如果只有一个,什么决定优先级?
如果你想要两者都活跃:
WITH t AS (SELECT MAX(stock) OVER (PARTITION BY Name, Param1, Param2, Param3) max_stock,* FROM Products)
UPDATE t
SET Active = CASE WHEN stock = max_stock THEN 1 ELSE 0 END
答案 1 :(得分:0)
我会说这就是你要找的东西。我不确定你为什么需要rownumber()
SELECT * FROM Products p1
INNER JOIN
(SELECT Name, PartNumber, MAX(Stock) AS MaxStock
FROM Products
GROUP BY Name, PartNumber) AS p2
ON p1.Name = p2.Name AND p1.PartNumber = p2.PartNumber AND p1.Stock = p2.MaxStock;
答案 2 :(得分:0)
我在sql server中使用RANK函数并在desc中对它进行排序,请参阅下面的代码:
select Id,
name,
partnumber,
param1,
param2,
param3,
stock,
active
from (
select *,
RANK() (parition by id, param1, param2, param3 order by stock desc) as max_stock
from product)x
where max_stock = 1