2016-12-30 4 views
2

У меня есть таблица ServiceItem, которая имеет Id, ParentId и некоторые свойства, такие как Name, Description и т. Д. Максимальный уровень иерархии 2. Мне нужен запрос, который выбирает строки с некоторым условием, например Name = '123' и его родительскую строку, чтобы получить как л:Выберите иерархию из таблицы

Id ParentId Name 
1 NULL  '12' 
2 1   '123' 

Я попытался это:

SELECT 
    * 
FROM ServiceItem si 
WHERE si.Name = '123' 
    OR EXISTS (
     SELECT 
      * 
     FROM ServiceItem syst 
      JOIN ServiceItem si2 
       ON si2.ParentId = syst.Id 
     WHERE syst.Id = si.ParentId 
      AND si2.Name = '123' 

    ) 

Но он возвращает родителя и всех его детей. Есть ли шанс сделать это с помощью одного запроса? Я использую T-SQL для этого.

Это отличается от this question, потому что мне нужно получить кучу строк, а не только Id по пути и условия в моем запросе могут быть разными.

+0

Возможный дубликат [Как пройти путь в таблице с id и parentId?] (Http://stackoverflow.com/question s/37197500/how-to-traverse-a-path-in-a-table-with-id-parentid) –

+0

@a_horse_with_no_name Нет, это не то, что я ищу. –

+0

Возможный дубликат [SQL Server CTE и пример рекурсии] (http://stackoverflow.com/questions/14274942/sql-server-cte-and-recursion-example). Вам нужно будет изменить запрос, чтобы начать дерево с нижней части дерева, а не сверху, но это по сути тот же синтаксис. –

ответ

1

Вы можете использовать Common Table Expression с помощью рекурсии:

WITH cte AS 
    (
    SELECT  * 
    FROM  ServiceItem 
    WHERE  Name = '123' 
    UNION ALL 
    SELECT  * 
    FROM  ServiceItem si 
    INNER JOIN cte 
      ON cte.ParentId = si.Id 
) 
SELECT * FROM cte 

Для более, например, в глубине, см this Q&A

+0

@trinkot Да, я работаю так, как мне это нужно. Благодарю. –

0
WITH cte AS 
    (
    SELECT  * 
    FROM  ServiceItem 
    WHERE  Name = '123' 
    UNION ALL 
    SELECT  * 
    FROM  ServiceItem si 
    INNER JOIN cte 
      ON cte.ParentId = si.Id 
) 
SELECT * FROM cte 

Это хороший вопрос, но я также нашел это:

SELECT 
    * 
FROM ServiceItem si 
WHERE si.Name = '123' 
    OR EXISTS (
     SELECT 
      * 
     FROM ServiceItem si2 
     WHERE si2.Name = '123' 
      and si2.ParentId = si.Id 
    ) 
Смежные вопросы