Это длинный, но я выделил важный материал.Сложная ситуация с SQL Server CTE: поиск родительской записи корня
Таким образом, я проверил сеть (в том числе здесь) на создание надлежащего CTE в SQL Server 2012. Я нашел множество резолюций, которые касаются того, как его построить, но из того, что я заметил (и еще) является CTE с внутренними соединениями. Я не уверен, что это смена игры, но мои попытки принести меня к стене. Поэтому я приношу свою дилемму этому сообществу в надежде, что у кого-то есть понимание. Я постараюсь сделать все возможное, чтобы помочь всем понять, откуда я родом.
В моей работе мне поручено создать новый графический интерфейс подтверждения приема сообщений, потому что по умолчанию, который поставляется с нашим программным обеспечением (Wonderware Archestra IDE), слишком мало для наших операторов, чтобы использовать их на сенсорных экранах. Я должен изобретать колесо с помощью системы меню сенсорного экрана, которую вы увидите в барах. Оператор будет выбирать сигнал тревоги и нажать кнопку подтверждения. Появляется графический интерфейс с настройками подтверждения.
Графический интерфейс, который я создаю, должен появиться и представить список кнопок вверху, который отображает имя каждой секции в растении (родитель корня), которое связано с сигналом тревоги. Нажатие на кнопку откроет список кнопок под ним, будь то причина подтверждения по сигналу или вспомогательная папка для их дальнейшего погружения по более конкретной причине. Я получил вторую часть, и я полностью настраиваю первую часть, где графический запрос будет запрашивать базу данных для извлечения всех связанных родительских записей в сигнал тревоги.
Ниже исходный запрос:
SELECT DISTINCT urg.reas_grp_desc, urg.reas_grp_id, urg.parent_reas_grp_id
FROM [MESDB].[dbo].[util_reas_link] url
inner join [MESDB].[dbo].[util_reas] ur on ur.reas_cd = url.reas_cd
inner join [MESDB].[dbo].[util_reas_grp] urg on urg.reas_grp_id = ur.reas_grp_id
where url.raw_reas_cd = @reasoncode
Результат исходного запроса:
reas_grp_desc reas_grp_id parent_reas_grp_id
General 0 NULL
TestSubFolder9 129 128
[util_reas_link] является таблица, которая содержит все возможные аварийные сигналы (первичный ключ) и все связанные причины подтверждения (внешний ключ).
[util_reas] - это таблица, содержащая все возможные причины подтверждения (первичный ключ) и все связанные разделы и подразделы завода (внешний ключ).
[util_reas_grp] - это таблица, содержащая все разделы и подразделы завода (первичный ключ), и каждая запись имеет идентификатор первичной группы и идентификатор родительской группы. Если запись имеет нуль в идентификаторе родительской группы, то она является корневым родителем этого раздела.
Этот запрос работал до тех пор, пока завод не захотел получить больше подтверждений в более тонкой степени. Причина в том, что старый запрос только проверял, кто был папкой родителя и дедушки по этому признаку. Теперь глубина может далеко походить на 9 папок в глубину.
Мой пересмотренный запрос (и дилемма) заключается в следующем:
;WITH CTE_REASON_GROUP
AS
(
SELECT urg.reas_grp_desc, urg.reas_grp_id, urg.parent_reas_grp_id, 1 as Lvl, urg.reas_grp_id as [RootGroupId]
FROM [MESDB].[dbo].[util_reas_grp] urg
where urg.parent_reas_grp_id is null
UNION ALL
SELECT urg.reas_grp_desc, urg.reas_grp_id, urg.parent_reas_grp_id, cterg.Lvl+1 as Lvl, cterg.RootGroupId
FROM [MESDB].[dbo].[util_reas_link] url
inner join [MESDB].[dbo].[util_reas] ur on ur.reas_cd = url.reas_cd
inner join [MESDB].[dbo].[util_reas_grp] urg on urg.reas_grp_id = ur.reas_grp_id
inner join CTE_REASON_GROUP cterg on cterg.reas_grp_id = urg.parent_reas_grp_id
where url.raw_reas_cd = @reasoncode
)
SELECT DISTINCT * FROM CTE_REASON_GROUP order by reas_grp_id
Я знаю, что происходит. Я знаю, что якорь извлекает всех корневых родителей. И я знаю, что второй внутренний запрос (исходный запрос с другим внутренним соединением для ссылки CTE_REASON_GROUP) извлекает только записи, которые оба связаны с кодом @reasoncode и REA_grp_id CTE_REASON_GROUP, который не дает никаких результатов.Это связано с тем, что только две записи были получены, как видно из выше, и ни один из родителей_reas_grp_id не будет соответствовать найденным якорям записям reas_grp_id.
Результат просто результаты анкера:
reas_grp_desc reas_grp_id parent_reas_grp_id Lvl RootGroupId
General 0 NULL 1 0
Pouring Station 1 NULL 1 1
Melting 2 NULL 1 2
Spray Booth 4 NULL 1 4
Core Room 10 NULL 1 10
Splitter 11 NULL 1 11
Stamper 12 NULL 1 12
Hot Wheel Grinding 13 NULL 1 13
Hub Cutting 14 NULL 1 14
Heat Treat 21 NULL 1 21
Core Baker 25 NULL 1 25
Я знаю, что я близок к ответу. Но я, похоже, не могу устранить разрыв в CTE с результатами, которые я хочу. Из исходного запроса General мне не нужно беспокоиться, потому что он является родителем-корнем с кодами причин в нем. TestSubFolder9 однако имеет 9 подпапок глубоко с кодом причины испытания. Его корневым родителем является CoreRoom.
В результате я ищу это потому, что корень родителя TestSubFolder9 в:
reas_grp_desc reas_grp_id parent_reas_grp_id Lvl RootGroupId
General 0 NULL 1 0
Core Room 10 NULL 1 10
Хотя длительный, я надеюсь, что это помогает всем здесь, чтобы понять, что я пытаюсь сделать и какой кусок головоломки я пропускаю в получите запись, в которой я нуждаюсь. Благодаря!
@AlexKuderyashev - вы, сэр гений. Это ТОЧНО, что мне нужно. Я знал, что это было что-то явно очевидное. Мне просто нужна была еще одна пара глаз, чтобы посмотреть, что я делаю. Небольшое изменение того, что вы предложили, например, использование Distinct в «SELECT * FROM CTE_REASON_GROUP порядке по lvl desc» и перемещение маленького столбца столбцов, но отличное от этого, является удивительным. СПАСИБО БОЛЬШОЕ! – vegeto18