如何仅选择其子表在其他表中引用的记录?

vla*_*dek 0 join sql-server

不确定问题的措辞是否正确,但这里有一个架构示例:

CREATE TABLE TabA (Id INT NOT NULL, PRIMARY KEY (Id));

CREATE TABLE TabB (
    Id INT NOT NULL, 
    TabAId INT, 
    PRIMARY KEY (Id),
    FOREIGN KEY (TabAId) REFERENCES TabA(Id)
)

CREATE TABLE TabC (
    Id INT NOT NULL, 
    TabAId INT, 
    PRIMARY KEY (Id),
    FOREIGN KEY (TabAId) REFERENCES TabA(Id)
)
Run Code Online (Sandbox Code Playgroud)

我需要做的是选择或(或两者)中的记录引用的TabA.Id位置。如果我以编程方式翻译这个:TabA.IdTabBTabC

type B = { Id : int }

type C = { Id : int }

type A = { ItemsB : B list ; ItemsC : C list }

let itemsA = [ ... ] // a list of items A
let filtered = itemsA |> List.filter (fun a -> a.ItemsB.Length > 0 || a.ItemsC.Length > 0)
Run Code Online (Sandbox Code Playgroud)

到目前为止,我尝试过这个查询,但我不确定它是否好:

type B = { Id : int }

type C = { Id : int }

type A = { ItemsB : B list ; ItemsC : C list }

let itemsA = [ ... ] // a list of items A
let filtered = itemsA |> List.filter (fun a -> a.ItemsB.Length > 0 || a.ItemsC.Length > 0)
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?谢谢。

SMo*_*Mor 5

为什么这么复杂?

SELECT a.Id 
FROM TabA a
WHERE exists (select * from TabB b where b.tabAId = a.Id)
   OR exists (select * from TabC c where c.tabAId = a.Id)
ORDER BY ...;
Run Code Online (Sandbox Code Playgroud)

这里不需要 DISTINCT - a.Id 是主键。在原始查询中,您可以使用 UNION 而不是 FULL OUTER JOIN。FULL OUTER JOIN 是无意义的 - 如果您仅测试查询的该部分并检查结果集,您就可以看到这一点。在这种情况下,需要使用 UNION 而不是 UNION ALL 来删除重复项。一般来说,UNION的使用最多的应该是UNION ALL。

当您遇到无法运行的查询问题时,请停止尝试立即修复所有问题。分解各个部分并检查它们的作用。通常,您会看到可以解决的问题,并且可能会引导您找到所需的逻辑。

要继续 UNION 注释,您可以使用:

SELECT b.TabAId AS Id FROM TabB as b
UNION 
SELECT c.TabAId FROM TabC as c
;
Run Code Online (Sandbox Code Playgroud)

根本不需要引用 TabA。