Выбор номера строки основного / вспомогательного элемента без подзапроса - PullRequest
0 голосов
/ 09 апреля 2019

Итак, я смотрю на таблицу под названием 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 - это «мастер» набора со значением «Y» в KIT_FLAG, а строки 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.

Я ценю любую проницательность.

1 Ответ

0 голосов
/ 10 апреля 2019

В итоге мне удалось отыскать решение, вычтя число вращения из номеров строк. Нет коррелированного подзапроса и выполняется в считанные секунды. Woo!

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...