所以我正在寻找一个名为LINEITEM的表,它列出了几个以“主/组件”排列的项目编号。他们称他们为工具包。这个想法是一个工具包可以包含任意数量的子项。这是一个简单的例子:
+----------+---------+---------+----------+-----------------+
| ORDER_NO | ITEM_ID | LINE_NO | KIT_FLAG | KIT_MASTER_LINE |
+----------+---------+---------+----------+-----------------+
| 858710 | 15291 | 1 | Y | 0 |
| 858710 | 113 | 2 | K | 1 |
| 858710 | 15279 | 3 | K | 1 |
| 858710 | 15292 | 4 | K | 1 |
| 858710 | 15321 | 5 | Y | 0 |
| 858710 | 106 | 6 | K | 5 |
| 858710 | 15563 | 7 | K | 5 |
| 858710 | 15564 | 8 | K | 5 |
| 858710 | 15296 | 9 | Y | 0 |
| 858710 | 116 | 10 | K | 9 |
| 858710 | 15479 | 11 | K | 9 |
| 858710 | 15480 | 12 | K | 9 |
+----------+---------+---------+----------+-----------------+
所以订购858710这里有3个套件。第1行是一个套件“master”,在KIT_FLAG中有一个值'Y',第2,3和4行以及该套件内的所有组件都带有值'K'。在我们到达第5行之前,已经使用第6,7和8行声明了第二个工具包作为其组件。
我需要在每个子项目上显示哪个订单项是它所属的“套件主人”。
我想要的输出是当前在KIT_MASTER_LINE列中显示的内容。我甚至可以用子查询来完成这个任务:
SELECT ORDER_NO, ITEM_ID, LINE_NO, KIT_FLAG,
ISNULL((
SELECT MAX(LINE_NO)
FROM LINEITEM AS l2
WHERE
l2.LINE_NO < li.LINE_NO
AND li.KIT_FLAG = 'K'
AND l2.KIT_FLAG = 'Y'
AND l2.ORDER_NO = li.ORDER_NO
), 0) AS 'KIT_MASTER_LINE'
FROM LINEITEM li
ORDER BY LINE_NO
...然而,执行计划并不缺乏深度,并且需要花费很多分钟来扫描大桌子。
我想我是否有更好的方法来使用窗口函数或类似功能。我的其他快速程序和所有它的优化都被这个必须两次调用LINEITEM表的挂断所破坏。
我很欣赏任何见解。
我最终能够通过从行号中减去旋转计数来追逐解决方案。没有相关的子查询,并在几秒钟内运行。呜!
SELECT *,
CASE WHEN KIT_FLAG = 'K'
THEN LINE_NO - ROW_NUMBER() OVER (PARTITION BY KIT_FLAG, [Group] ORDER BY LINE_NO)
ELSE 0
END AS 'KIT_MASTER_LINE'
FROM (
SELECT ORDER_NO, ITEM_ID, LINE_NO, KIT_FLAG,
ROW_NUMBER() OVER (ORDER BY ORDER_NO, LINE_NO) - ROW_NUMBER() OVER (PARTITION BY KIT_FLAG ORDER BY ORDER_NO, LINE_NO) AS [Group]
FROM LINEITEM
) AS [GroupTable]
ORDER BY ORDER_NO, LINE_NO