假设三张表:
create table table_a( id int generated by default as identity primary key);
create table table_c( id int generated by default as identity primary key
, active boolean);
create table table_b( id int generated by default as identity primary key
, active boolean
, table_a_id int references table_a(id)
, table_c_id int references table_c(id));
table_a
中的行可以通过table_c
与table_b
中的行相关。table_c
和 table_b
各有一个 boolean
属性,称为 active
。
如何编写 SQL 语句或活动记录表达式来获取每个
table_a
记录
table_b
记录显示 active
另存为 true
table_b
记录,但没有一个链接到 table_c
行且 active
保存为 true
?输入示例:
db<>fiddle 的演示
with populated_a as
(insert into table_a values
(1) --YES, doesn't have a `b` or `c` at all
,(2) --NO, has an active `b`
,(3) --YES, has a `b` but it's inactive
,(4) --NO, has both an active `b` and active `c`
,(5) --YES, has an active `b` but it links to an inactive `c`
,(6) --YES, has an inactive `b` and it links to an inactive `c`
returning *)
,populated_c as
(insert into table_c values(2,false)
,(3,true)
,(4,true)
,(5,false)
,(6,false)
,(7,true)--no associated `a` or `b`
returning *)
insert into table_b(active,table_c_id,table_a_id)
values (true,2,2)
,(false,3,3)
,(true,4,4)--also links to active `c`
,(true,5,5)--links to inactive `c`
,(false,6,6);
我的尝试:
SELECT "table_a".* FROM "table_a"
LEFT OUTER JOIN "table b"
ON "table_b"."table_a_id" = "table_a"."id"
AND "table_b"."active" = true
LEFT OUTER JOIN "table_c"
ON "table_b"."table_c_id" = "table_c"."id"
AND "table_c"."active" = true
WHERE "table_b"."id" IS NULL OR "table_c"."id" IS NULL
预期输出是行
(1,3,5,6)
。我的代码返回它们全部,但它也错误地返回 2
,其中有一个活动的 b
。
基本上,我在彼此深处做了两个 LEFT OUTER JOIN,最终按照我的预期工作:
SELECT "table_a".* FROM "table_a"
LEFT OUTER JOIN "table b"
ON "table_b"."table_a_id" = "table_a"."id"
AND "table_b"."active" = true
LEFT OUTER JOIN "table_c"
ON "table_b"."table_c_id" = "table_c"."id"
AND "table_c"."active" = true
WHERE "table_b"."id" IS NULL OR "table_c"."id" IS NULL