有2个表:
people
+------------+--------------+------+
| name | place | pid |
+------------+--------------+------+
| Mr John | place1 | 1 |
| Miss Smith | place2 | 2 |
+------------+--------------+------+
places
+------+------+----------------------+
| pid | owner| address |
+------+------+----------------------+
| 1 | 1 | address1 |
| 1 | null | address2 |
| 2 | null | address3 |
| 2 | null | address4 |
| 2 | null | address5 |
+------+------+----------------------+
我正在寻找一个将返回的查询:
people (complex left join) places on people.pid = places.pid
Mr John | place1 | 1 | 1 | 1 | address1
Miss Smith | place2 | 2 | 2 | null | address3
Miss Smith | place2 | 2 | 2 | null | address4
Miss Smith | place2 | 2 | 2 | null | address5
单词pid
上的联接,但如果特定owner
存在非空person
值,则只获取该行,如果不存在非空{{1}然后获取特定owner
的所有行。使用左连接,因为我还需要person
people
答案 0 :(得分:3)
一种策略是预先处理CTE中的places
表,以确定哪个pid
组记录至少有一个非NULL
所有者值。此类pid
记录需要全部包含在联接中。另一方面,如果pid
群组至少有一位非NULL
所有者,那么我们只会在联接中包含非NULL
个匹配项。
WITH cte AS (
SELECT pid, owner, address,
SUM(CASE WHEN owner IS NOT NULL THEN 1 ELSE 0 END) OVER
(PARTITION BY pid) AS non_null_cnt
FROM places
)
SELECT t1.name, t1.place, t1.pid, t2.owner, t2.address
FROM people t1
LEFT JOIN cte t2
ON t1.pid = t2.pid AND
(t2.owner IS NOT NULL OR t2.non_null_cnt = 0)
ORDER BY t1.pid;
答案 1 :(得分:1)
;WITH CTE as
(
SELECT count(owner)over(partition by pid) mo,*
FROM places
)
SELECT *
FROM people p
LEFT JOIN CTE
ON
p.pid = CTE.pid
and (mo = 0
or owner is not null)