![](/img/trans.png)
[英]SQL Query to get records of parent table that have a list of child records
[英]Write a SQL query to get the only Super Child records from the Table
我正在努力准備一個SQL查詢,該查詢應一次性返回期望的數據。
我的要求是以這種方式從名為JobCollection的 SQl表中獲取數據,以使其返回數據,如下圖的綠色邊框突出顯示。
此數據以父子方式進行組織。 如下所示,
條件:
如綠色邊框所示,JCId 8,9,10,11和12不是任何記錄的父項
此外,綠色邊框突出顯示了JCId 1而不是JCId 2的超級子級
請注意,這是一個示例,我們不能使用存儲過程或游標。 並且層次結構級別是未定義的。 可以是任何東西。
更新:
再舉一個例子
我只想用紅色突出顯示那些記錄。 如您所見,綠色邊框表明這些是每個記錄的超級子記錄,而紅色突出顯示了JCId 1的超級子記錄。
我要求每個人發自內心地仔細閱讀該問題,並理解其中的痛苦,然后再投票反對該問題。 我真的很難獲得預期的結果
有很多方法。 這是1。
select whatever
from table t1 left join table t2 on jcid = jcparentid
where t2.jcid is null
也許比您需要的多一點,但如果需要,可以將其縮小。
這里的技巧是使用范圍鍵R1 / R2。
Declare @YourTable table (JCId int,JCParentId int,JCName varchar(50))
Insert into @YourTable values
( 1, NULL,'A')
,( 2, NULL,'B')
,( 3, 1 ,'A1')
,( 4, 1 ,'A2')
,( 5, 1 ,'A3')
,( 6, 2 ,'B1')
,( 7, 2 ,'B2')
,( 8, 3 ,'A11')
,( 9, 3 ,'A12')
,(10, 4 ,'A21')
,(11, 5 ,'A31')
,(12, 5 ,'A32')
,(13, 6 ,'B11')
,(14, 6 ,'B12')
,(15, 7 ,'B21')
,(16, 7 ,'V22')
Declare @Top int = 1 --null --<< Sets top of Hier Try 3
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability
;with cteP as (
Select Seq = cast(10000+Row_Number() over (Order by JCName) as varchar(500))
,JCId
,JCParentId
,Lvl=1
,JCName
From @YourTable
Where IsNull(@Top,-1) = case when @Top is null then isnull(JCParentId ,-1) else JCId end
Union All
Select Seq = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.JCName)) as varchar(500))
,r.JCId
,r.JCParentId
,p.Lvl+1
,r.JCName
From @YourTable r
Join cteP p on r.JCParentId = p.JCId)
,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP)
,cteR2 as (Select A.JCId,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.JCId )
Select A.R1
,B.R2
,A.JCId
,A.JCParentId
,A.Lvl
,JCName = Replicate(@Nest,A.Lvl-1) + A.JCName
From cteR1 A
Join cteR2 B on A.JCId=B.JCId
and R1=R2
退貨
當@Top = NULL且您刪除最終的且R1 = R2時為完全層次結構
使用遞歸JCId
來獲取一個JCId
所有JCId
,然后使用not exists()
選擇那些沒有自己子代的子孫:
declare @ParentId int;
set @ParentId = 1;
with cte as (
select JCId, JCName, JCParentId, JCParentName
from JobCollection
where JCId = @ParentId
union all
select c.JCId, c.JCName, c.JCParentId, c.JCParentName
from JobCollection c
inner join cte p on p.JCId = c.JCParentId
)
select JCId, JCName, JCParentId, JCParentName
from cte as o
where not exists (
select 1
from cte as i
where o.JCid = i.JCParentId
);
測試設置: http : //rextester.com/LGEQD6195
create table JobCollection (
JCId int
, JCName varchar(50)
, JCParentId int
, JCParentName varchar(50)
);
insert into JobCollection values
( 1, 'A' , null, null)
,( 2, 'B' , null, null)
,( 3, 'A1' , 1, null)
,( 4, 'A2' , 1, null)
,( 5, 'A3' , 1, null)
,( 6, 'B1' , 2, null)
,( 7, 'B2' , 2, null)
,( 8, 'A11', 3, null)
,( 9, 'A12', 3, null)
,(10, 'A21', 4, null)
,(11, 'A31', 5, null)
,(12, 'A32', 5, null)
,(13, 'B11', 6, null)
,(14, 'B12', 6, null)
,(15, 'B21', 7, null)
,(16, 'B22', 7, null);
查詢:
declare @ParentId int;
set @ParentId = 1;
with cte as (
select JCId, JCName, JCParentId, JCParentName
from JobCollection
where JCId = @ParentId
union all
select c.JCId, c.JCName, c.JCParentId, JCParentName = p.JCName
from JobCollection c
inner join cte p on p.JCId = c.JCParentId
)
select JCId, JCName, JCParentId, JCParentName
from cte as o
where not exists (
select 1
from cte as i
where o.JCid = i.JCParentId
);
結果:
+------+--------+------------+--------------+
| JCId | JCName | JCParentId | JCParentName |
+------+--------+------------+--------------+
| 11 | A31 | 5 | A3 |
| 12 | A32 | 5 | A3 |
| 10 | A21 | 4 | A2 |
| 8 | A11 | 3 | A1 |
| 9 | A12 | 3 | A1 |
+------+--------+------------+--------------+
我將嘗試一下:
SELECT JcId FROM JobCollection
WHERE JcId NOT IN (SELECT JcParentId FROM JobCollection)
更新:僅當JcParentId = 1時選擇
SELECT JcId FROM JobCollection
WHERE JcId NOT IN (SELECT JcParentId FROM JobCollection)
AND JcParentId = 1
這應該工作!
SELECT distinct J1.*
from JobCollection J1
LEFT JOIN JobCollection J2 ON J1.JCId = J2.JcParentId
WHERE J2.JcParentId IS NULL
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.