如果subId是其他项目的ID,则从同一表中检索数据

时间:2019-05-08 17:19:25

标签: sql oracle

我有一个包含一些记录的表,我只想将这些具有subID的记录添加到值为id的{​​{1}}的记录中。如果没有subID行,则不要将此行带到表中。如果表中已有值,也不要重复,也不要查看id为0的行,因为它们可以像subId那样,所以它们没有parents

----------------------------
ID | SUBID | NAME | ENABLED |
30 | 0     | EXP1 | TRUE    |
55 | 30    | EXP2 | TRUE    |
70 | 30    | EXP3 | FALSE   |
99 | 42    | EXP4 | FALSE   |
232| 0     | EXP5 | TRUE    |
65 | 232   | EXP6 | TRUE    |
-----------------------------

预期结果:

----------------------------
ID | SUBID | NAME | ENABLED |
30 | 0     | EXP1 | TRUE    |
55 | 30    | EXP2 | TRUE    |
70 | 30    | EXP3 | FALSE   |
232| 0     | EXP5 | TRUE    |
65 | 232   | EXP6 | TRUE    |
-----------------------------

如果有人可以帮助我如何很好地编写此childs,我将不胜感激。

5 个答案:

答案 0 :(得分:1)

您可以使用“存在”:

SELECT T1.* FROM TEST T1
WHERE EXISTS (SELECT T2.ID FROM TEST T2 WHERE T2.ID = T1.SUBID)
   OR EXISTS (SELECT T3.SUBID FROM TEST T3 WHERE T3.SUBID = T1.ID)

测试结果:

DB<>Fiddle

答案 1 :(得分:0)

工会怎么样

select a.*
from have a
inner join have b
    on a.subid=b.id
union
select b.*
from have a
inner join have b
    on a.subid=b.id;

答案 2 :(得分:0)

正如您已经发现的那样,这实际上可能非常复杂。我建议您为CTE和UNION加上JOIN和别名。看起来它还需要在子查询中完成DISTINCT。

如果不对此进行测试,我会使其看起来像这样:

WITH MAIN AS (  
SELECT ID, SUBID, NAME  
FROM TABLE t  
WHERE ENABLED = TRUE  
)

SELECT DISTINCT ID, NAME  
FROM (
    SELECT ID, NAME  
    FROM MAIN
    UNION
    SELECT t.ID, t.NAME 
    FROM MAIN
    LEFT JOIN TABLE t on MAIN.SUBID = t.ID
    WHERE MAIN.SUBID <> 0
)

如果您对每个内部查询执行不同操作,则可能不需要外部选择,但是如果不进行测试,则不能确定。我想这只会分别区分两个列表,这不是您想要的结果。

我有点希望其他人可以提出一个不太复杂的版本。我还建议您对CTE,UNION,别名进行更多研究,看看是否可以自己简化此过程。但这应该可以指引您正确的方向。

顺便说一句,我使用了CTE(主要方式),以便查询不会重复。

答案 3 :(得分:0)

尝试此脚本-

SELECT YT.* 
FROM your_table YT
INNER JOIN (
    SELECT DISTINCT(B.ID)
    FROM your_table A
    LEFT JOIN your_table B 
        ON A.SUBID = B.ID
    WHERE B.ID IS NOT NULL
) C ON YT.ID = C.ID OR YT.SUBID = C.ID

答案 4 :(得分:0)

根据我对您要做什么的了解,您只是想要:

SELECT * FROM myTable t1
  WHERE SubID = 0
     OR EXISTS (SELECT NULL FROM myTable t2 WHERE t2.id = t1.SubID)