2016-05-13 7 views
0

Это длинный, но я выделил важный материал.Сложная ситуация с 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 

Хотя длительный, я надеюсь, что это помогает всем здесь, чтобы понять, что я пытаюсь сделать и какой кусок головоломки я пропускаю в получите запись, в которой я нуждаюсь. Благодаря!

ответ

0

Вы должны инвертировать КТР, как это идти вверх по иерархии:

;WITH CTE_REASON_GROUP 
AS 
(
SELECT urg.reas_grp_desc, urg.reas_grp_id, urg.parent_reas_grp_id, 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 
where url.raw_reas_cd = @reasoncode 
UNION ALL 

SELECT urg.reas_grp_desc, urg.reas_grp_id, urg.parent_reas_grp_id, cterg.Lvl+1 as Lvl, urg.reas_grp_id as [RootGroupId] 
FROM [MESDB].[dbo].[util_reas_grp] urg 
inner join CTE_REASON_GROUP cterg on urg.reas_grp_id = cterg.parent_reas_grp_id 
--where urg.parent_reas_grp_id is null 

) 
SELECT * FROM CTE_REASON_GROUP 
order by lvl desc --reas_grp_id 
+0

@AlexKuderyashev - вы, сэр гений. Это ТОЧНО, что мне нужно. Я знал, что это было что-то явно очевидное. Мне просто нужна была еще одна пара глаз, чтобы посмотреть, что я делаю. Небольшое изменение того, что вы предложили, например, использование Distinct в «SELECT * FROM CTE_REASON_GROUP порядке по lvl desc» и перемещение маленького столбца столбцов, но отличное от этого, является удивительным. СПАСИБО БОЛЬШОЕ! – vegeto18

Смежные вопросы