2016-10-19 10 views
0

Мне нужно найти заголовок '%p%'. если я проверяю заголовок, родительскую плитку и статус родительского и дочернего уровней. , если искомый родительский элемент заголовка является истинным, тогда отобразите дочернее название.Как выбрать заголовок, используя родительскую и дочернюю иерархию в sql?

SELECT title 
FROM table1 t1 
JOIN table1 t2 ON t1.title = t2.parenttitle AND t1.visible = TRUE 
JOIN table1 t3 ON t3.title = t2.parenttitle AND t3.visible = TRUE 
WHERE t1.title LIKE '%p%' 

Table1

Title | ParentTitle|visible 
P1  Home   TRUE 
p1.1  p1   TRUE 
p1.2  p1   FALSE  
p1.3  p1.2  TRUE 
p1.3.1  p1.3  TRUE 
p2   Home  TRUE 
p2.1  p2   TRUE 
p2.2  p2.1  FALSE  
P3   Home  TRUE 
p3.1  p3   TRUE 
P3.1.1  p3.1  FALSE  

Мне нужен выход, как

title 
p1 
p1.1 
p2 
p2.1 
P3 
p3.1 
+0

Используйте столбец 'hierarchyid' вместо того, чтобы пытаться найти родителя, используя заголовок. Использование названия в качестве ключа - это не очень хорошая идея, так или иначе, –

+0

любой образец @PanagiotisKanavos – Meline

+0

Попробуйте googling для 'hierarhcyid'. SQL Server имеет отличную документацию с множеством примеров и многими функциями для обработки иерархии, получения дочерних или родительских узлов и т. Д. Я думаю, что второй результат - [учебник] (https://msdn.microsoft.com/en-us/library /bb677213.aspx) о том, как [преобразовать существующую таблицу] (https://msdn.microsoft.com/en-us/library/bb677237.aspx) и [запросить иерархическую таблицу] (https://msdn.microsoft .com/en-us/library/bb677270.aspx), включая [примеры запросов] (https://msdn.microsoft.com/en-us/library/bb677191.aspx), чтобы найти родителей, детей, корни, уровень и т. д. –

ответ

1
CREATE TABLE CTE(
    Title VARCHAR(20), 
    ParentTitle VARCHAR(20), 
    visible VARCHAR(20),  
) 

INSERT INTO CTE 
VALUES 
('p1', 'Home', 'TRUE'), 
('p1.1', 'p1', 'TRUE'), 
('p1.2', 'p1', 'FALSE'),  
('p1.3', 'p1.2', 'TRUE'), 
('p1.3.1', 'p1.3', 'TRUE'), 
('p2', 'Home', 'TRUE'), 
('p2.1', 'p2', 'TRUE'), 
('p2.2', 'p2.1', 'FALSE'),  
('P3', 'Home', 'TRUE'), 
('p3.1', 'p3', 'TRUE'), 
('P3.1.1', 'p3.1', 'FALSE') 


; WITH YTE AS 
(
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY LEFT(A.Title, 2) ORDER BY A.Title) AS RN, 
    DENSE_RANK() OVER(ORDER BY LEFT(A.Title, 2)) AS DR 
    FROM CTE A 
) 
, ZTE AS 
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY LEFT(A.Title, 2) ORDER BY A.Title) AS RNFalse 
    FROM YTE A 
    WHERE A.visible = 'FALSE' 
) 
, ATE AS 
(
    SELECT A.Title 
    FROM YTE A 
    INNER JOIN ZTE B ON A.DR = B.DR AND A.RN < B.RN 
    WHERE RNFalse = 1 
) SELECT * FROM ATE 

/* 
Output: 
p1 
p1.1 
p2 
p2.1 
P3 
p3.1 
*/ 

Если вы не хотите использовать общее табличное выражение, а затем использовать подзапросы

SELECT A.Title FROM 
(
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY LEFT(A.Title, 2) ORDER BY A.Title) AS RN 
    FROM CTE A 
) AS A 
INNER JOIN 
(
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY LEFT(A.Title, 2) ORDER BY A.Title) AS RNFalse 
    FROM 
    (
     SELECT *, 
     ROW_NUMBER() OVER(PARTITION BY LEFT(A.Title, 2) ORDER BY A.Title) AS RN 
     FROM CTE A 
    ) A 
    WHERE A.visible = 'FALSE' 
) AS B ON LEFT(A.Title, 2) = LEFT(B.Title, 2) AND A.RN < B.RN 
WHERE B.RNFalse = 1 

Так что, если вы хотите удалить ROW_NUMBER, тогда вы должны сравнить varchar, что не очень хорошо. Но другого пути ты не оставил для меня. Попробуйте это,

SELECT A.Title FROM CTE A 
INNER JOIN 
(
    SELECT LEFT(Title, 2) AS TitleGroup, Min(Title) AS Title 
    FROM CTE 
    WHERE visible = 'False' 
    GROUP BY LEFT(Title, 2) 
) B ON LEFT(A.Title, 2) = B.TitleGroup 
AND A.Title < B.Title --Comparing String like this is not good 
+0

Спасибо @Tanjim Rahman ..... вы можете мне помочь PLS ..... можно получить без рекурсивного ... – Meline

+0

Где вы получаете рекурсию здесь !!!! – Esty

+0

Использование любых соединений .. возможно ... @ Tanjim Rahman – Meline

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

  • Нет связанных вопросов^_^