area
-----
id BIGSERIAL PRIMARY KEY
deleted_at TIMESTAMP WITH TIME ZONE DEFAULT NULL
和
registration
-----
area_id BIGINT REFERENCES area(id) NOT NULL
我想从area
具有deleted_at IS NULL
所有记录,并且可以有deleted_at is NOT NULL
但存在作为registration
一个FK的人。
SELECT * FROM area
JOIN registration AS reg
ON reg.area_id=area.id
WHERE area.deleted_at IS NULL;
将省略area
记录这是在registration
FKS但都被标记为“已删除”。
添加关于AND
子句中的列deleted_at
的JOIN ON
条款没有任何意义,因为它只会去掉有效记录。
我不能完全将其套在我的头上,因为这两个where
条件那种相互矛盾。
尝试是这样的:
SELECT *
FROM area
LEFT JOIN registration AS reg ON reg.area_id = area.id
WHERE (area.deleted_at IS NULL) <> (reg.area_id IS NOT NULL)
该LEFT JOIN
会列出所有area
行,即使没有registration
匹配的行。 (对于这些行所得NULL
值)。
该WHERE
条款可以确保两个领域都没有在同一时间NULL
s。
我觉得这是你要求的。当您使用左加入它的注册数据字段将显示为空在那里他们没有出现在报名表中。
select * from area
left join registration as reg
on reg.area_id= area.id
where area.deleted_at is null or reg.area_id is not null;
-- I need (0) all area records EXCEPT the ones where (1) deleted_at IS NOT NULL
-- AND (2) are NOT present as FKs in registration.
SELECT * FROM area a
WHERE NOT(
a.deleted_at IS NOT NULL -- (1)
AND NOT EXISTS (
SELECT * -- (2)
FROM registration r
WHERE r.area_id=a.id
)
);
注意:你的文字措辞是混乱:EXCEPT a AND b
可能意味着两件事
而且,问题的改述后:
-- I want to get (0) all records from area (1) which have deleted_at IS NULL (1a)
-- and (2) the ones that can have deleted_at is NOT NULL but are present as a FK in the registration.
SELECT * FROM area a
WHERE a.deleted_at IS NULL -- (1)
OR a.deleted_at IS NOT NULL AND EXISTS ( (1a)
SELECT * -- (2)
FROM registration r
WHERE r.area_id=a.id
);
如果我理解正确的话,你的意思是加在那些(1A):如果是这样,和(1a)中被转换成一个或
你只需搜索以下查询?
SELECT * FROM Area
LEFT OUTER JOIN registration on id = area_id
WHERE deleted_at IS NULL OR area_id IS NOT NULL
这将在同一area.id
多次返回,如果registration.area_id
不是唯一的,虽然(因为你没有UNIQUE
约束)。
如果这是一个问题,您可能希望下面的查询来代替。
SELECT * FROM Area
WHERE deleted_at IS NULL OR id IN (SELECT area_id FROM registration)
还是这个,有COUNT
内置:
SELECT id, deleted_at, COUNT(*) FROM Area
LEFT OUTER JOIN registration on id = area_id
WHERE (deleted_at IS NULL or area_id IS NOT NULL)
GROUP BY id, deleted_at