2013-11-26 62 views
0

我們有這臺產品在商店用這樣的價值觀:SQL選擇的行數,並用相等值的多個行的標識值

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 

正如你可以看到有具有相同名稱的產品,而params,但不同的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 

,因爲我們是從外部源(web服務)接收的庫存數量,每天每個股票更新後幾次這個過程是必需的,我們需要評估其應保持活躍。

我們做在這一刻什麼和工作正常,但沒有一個良好的性能是使用存儲過程執行以下操作:

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

我用RANK函數在SQL Server中,並責令在遞減,見下面的代碼:

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

謝謝!奇蹟般有效。只有一個精度,你在RANK()後錯過了OVER。 – ramvanet

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 
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;