1

我找不到一個函數來支持我正在嘗試的方法。SQL Row_Number()(分區由...排序依據...)IGNORES命令語句

讓我們假設我們有如下表,包含一個字段排序順序和一定的重複

 
+----------+----------+-----+-------------+-----------+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | 
+----------+----------+-----+-------------+-----------+ 
|  3124 | 92361725 | 25 |  269.99 |   1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 
|  3791 | 92361725 | 20 |  269.99 |   5 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 
+----------+----------+-----+-------------+-----------+ 

我要列舉我行增加其價值,當副本被發現,如果沒有則重置行號。結果必須在列中顯示RN下表,如果數量是評價柱:

 
+----------+----------+-----+-------------+-----------+----+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | rn | 
+----------+----------+-----+-------------+-----------+----+ 
|  3124 | 92361725 | 25 |  269.99 |   1 | 1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 4 | 
|  3791 | 92361725 | 20 |  269.99 |   5 | 1 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 1 | 
+----------+----------+-----+-------------+-----------+----+ 

我試圖用ROW_NUMBER()函數,但我不能讓我的結果想

;WITH Table1 AS(
SELECT 3124 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 1 SortOrder UNION ALL 
SELECT 2627 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 2 SortOrder UNION ALL 
SELECT 7635 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 3 SortOrder UNION ALL 
SELECT 8732 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 4 SortOrder UNION ALL 
SELECT 3791 UniqueId,92361725 Id, 20 Qty, 269.99 RetailPrice, 5 SortOrder UNION ALL 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 6 SortOrder 
) 

SELECT UniqueId, Id, Qty, RetailPrice, SortOrder, 
ROW_NUMBER() OVER (PARTITION BY Qty ORDER BY SortOrder) rn 
FROM Table1 
 
+----------+----------+-----+-------------+-----------+----+ 
| UniqueId | Id | Qty | RetailPrice | SortOrder | rn | 
+----------+----------+-----+-------------+-----------+----+ 
|  3791 | 92361725 | 20 |  269.99 |   5 | 1 | 
|  3124 | 92361725 | 25 |  269.99 |   1 | 1 | 
|  2627 | 92361725 | 25 |  269.99 |   2 | 2 | 
|  7635 | 92361725 | 25 |  269.99 |   3 | 3 | 
|  8732 | 92361725 | 25 |  269.99 |   4 | 4 | 
|  4328 | 92361725 | 25 |  269.99 |   6 | 5 | 
+----------+----------+-----+-------------+-----------+----+ 

在ORDER BY完全被忽略,任何人都可以幫忙嗎?

+5

ORDER BY不會被忽略。如果按Qty進行分區,則將第6行與第1-4行分組。你需要嘗試一個「差距和離島」的方法。看看LAG功能。 –

+0

它根本沒有被忽略。盯緊了。您正在根據「數量」列對結果進行分區。因此,在第一個分區中,「rn」是1.在下一個分區中,「rn」基於「Qty」。你還想要什麼? – ViKiNG

+0

謝謝Tab Alleman,但不幸的是,這必須在2008 R2數據庫引擎中接近,因爲我在標籤中指定了 –

回答

1

你在這裏。由於您是在2008年,我通過在SortOrder +/- 1上自行加入此表來複制Lead和Lag。我還更新了您的樣本組,以便爲​​數量爲25的新島嶼進行了更新。

對不起,我有更新您的樣品組以添加2行到3號島,並創建2個CTE以獲取島範圍。

--Updates Sample Set with 3 Islands. 
WITH Table1 AS(
SELECT 3124 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 1 SortOrder UNION ALL --Island 1 
SELECT 2627 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 2 SortOrder UNION ALL --Island 1 
SELECT 7635 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 3 SortOrder UNION ALL --Island 1 
SELECT 8732 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 4 SortOrder UNION ALL --Island 1 
SELECT 3791 UniqueId,92361725 Id, 20 Qty, 269.99 RetailPrice, 5 SortOrder UNION ALL --Island 2 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 6 SortOrder UNION ALL --Island 3 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 7 SortOrder UNION ALL --Island 3 
SELECT 4328 UniqueId,92361725 Id, 25 Qty, 269.99 RetailPrice, 8 SortOrder   --Island 3 
), 

--Creating a CTE to get the Lead and Lag since this is 2008. This will allow us to determine if a row is the first or last row of an island. 
LeadLagTable AS(
SELECT 
    Table1.UniqueId, 
    Table1.Id, 
    Table1.Qty, 
    Table1.RetailPrice, 
    Table1.SortOrder, 
    LeadTable.SortOrder AS LeadSortOrder, 
    LagTable.SortOrder AS LagSortOrder, 
    CASE 
     WHEN LagTable.SortOrder IS NULL THEN 1 
     ELSE 0 
     END AS StartRowFlag, 
    CASE 
     WHEN LeadTable.SortOrder IS NULL THEN 1 
     ELSE 0 
     END AS LastRowFlag 
FROM Table1 
LEFT JOIN Table1 LeadTable ON 
    Table1.SortOrder = LeadTable.SortOrder - 1 
    AND Table1.Qty = LeadTable.Qty 
LEFT JOIN Table1 LagTable ON 
    Table1.SortOrder = LagTable.SortOrder + 1 
    AND Table1.Qty = LagTable.Qty 
), 

--With the LeadLagTable we can now get the ranges for each island, as well as a unique ID for each island. 
Ranges AS (
SELECT 
    RangeStart, 
    RangeEnd, 
    ROW_NUMBER() OVER (ORDER BY RangeStart) AS RangeRowNum 
FROM (
    SELECT 
     StartRow.SortOrder AS RangeStart, 
     EndRow.SortOrder RangeEnd, 
     ROW_NUMBER() OVER (PARTITION BY StartRow.SortOrder ORDER BY EndRow.SortOrder) AS rn 
    FROM LeadLagTable StartRow 
    JOIN LeadLagTable EndRow ON 
     StartRow.StartRowFlag = 1 
     AND EndRow.LastRowFlag = 1 
     AND StartRow.SortOrder <= EndRow.SortOrder 
     AND StartRow.Qty = EndRow.Qty 
    ) tbl 
WHERE rn = 1 
) 

這裏是實際的查詢。

--We now join on the island ranges, and partition by the Island ID. 
SELECT 
    UniqueId, 
    Id, 
    Qty, 
    RetailPrice, 
    SortOrder, 
    ROW_NUMBER() OVER (PARTITION BY RangeRowNum ORDER BY SortOrder) AS rn 
FROM Table1 
LEFT JOIN Ranges ON 
    Table1.SortOrder >= Ranges.RangeStart 
    AND Table1.SortOrder <= Ranges.RangeEnd 
+0

我剛剛意識到,這與所提供的樣本數據一起工作,但如果您有額外的數量爲25的訂單並且有效的超前/滯後,則不會擴展。他們繼續之前停止的地方。檢查。 –

+0

更新了答案。這應該工作,但取決於表大小,可能是內存密集型。 –

+0

是的,我在這裏有完整的場景,非常適合。很多很多謝謝努力 –