簡體   English   中英

編寫SQL查詢以從表中獲取唯一的超級子記錄

[英]Write a SQL query to get the only Super Child records from the Table

我正在努力准備一個SQL查詢,該查詢應一次性返回期望的數據。

我的要求是以這種方式從名為JobCollection的 SQl表中獲取數據,以使其返回數據,如下圖的綠色邊框突出顯示。

此數據以父子方式進行組織。 如下所示,

  • JCId 1是JCId 3、4、5的ParentID。 與JCId 2相同的是JCId 6,7的ParentID。
  • 此外,JCId 3、4、5也是8、9、10、11、12等的ParentId。

條件:

  • 我只想從JobCollection表中獲取那些記錄,這些記錄的JCId不是任何其他記錄的父級。

如綠色邊框所示,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM