我找不到支持我想要接近的功能。
假设我们有下表,其中包含字段排序顺序和某些重复项
+----------+----------+-----+-------------+-----------+ | 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 | +----------+----------+-----+-------------+-----------+
我希望枚举我的行,当找到重复时增加它们的值,如果没有则重置行号。如果 Qty 是要评估的列,则结果必须显示在下表中的 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完全被忽略,有人可以帮忙吗?
答案 0 :(得分:1)
你走了。自从你在2008年,我通过在SortOrder +/- 1上自己加入这个表来复制Lead和Lag。我还更新了你的样本集,以便考虑到新的25个岛屿。
对不起文字墙,但我不得不更新你的样本集,向岛3添加2行,并创建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