2016-10-19 51 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%' 

表1

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

嘗試搜索'hierarhcyid'。 SQL Server具有優秀的文檔,其中包含許多示例和許多函數來處理層次結構,檢索子節點或父節點等。我認爲第二個結果是[tutorial](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拉赫曼.....你可以幫我請.....可能得到沒有遞歸... – Meline

+0

你在哪裏得到遞歸!!!! – Esty

+0

使用任何連接..如果可能... @ Tanjim Rahman – Meline

相關問題