加入两列,如果为空则只加入一列
Join on two columns, if null then only join on one
我有以下两个表:
客户:
customer_id
department_id
aaaa
1234
bbbb
3456
状态:
department_id
customer_id
status
1234
NULL
silver
3456
bbbb
gold
1234
bbbb
gold
我想加入客户的状态,但是如果它 returns NULL 我想给客户部门默认值。我的理想输出如下:
customer_id
department_id
status
aaaa
1234
silver
bbbb
3456
gold
我尝试进行两次左连接,但出现内存使用错误。还有其他有效的方法吗?
你可以这样做:
select c.*, coalesce(s.status, d.status) as status
from customers c
left join status d on d.department_id = c.department_id
and d.customer_id is null
left join status s on s.department_id = c.department_id
and s.customer_id = c.customer_id
这可能有效:
SELECT *,
(
SELECT TOP 1 status
FROM status s
WHERE s.customer_id = c.customer_id
OR (c.customer_id IS NULL AND s.department_id = c.department_id)
ORDER BY CASE WHEN s.customer_id is NOT NULL THEN 0 ELSE 1 END
) as status
FROM customers c
关键在于您使用的是哪种数据库。如果是 MySql,您可能需要 LIMIT 1 而不是 TOP 1。对于 Oracle,您需要查看 ROWNUM 字段。
假设至少在 department_id
上始终存在匹配项,您需要一个 INNER
连接并且 FIRST_VALUE()
window 函数将选择正确的 status
:
SELECT DISTINCT
c.customer_id,
c.department_id,
FIRST_VALUE(s.status) OVER (
PARTITION BY c.customer_id, c.department_id
ORDER BY CASE
WHEN s.customer_id = c.customer_id THEN 1
WHEN s.customer_id IS NULL THEN 2
ELSE 3
END
) status
FROM customers c INNER JOIN status s
ON s.department_id = c.department_id;
根据您使用的数据库,代码可能会被简化。
参见demo。
我有以下两个表:
客户:
customer_id | department_id |
---|---|
aaaa | 1234 |
bbbb | 3456 |
状态:
department_id | customer_id | status |
---|---|---|
1234 | NULL | silver |
3456 | bbbb | gold |
1234 | bbbb | gold |
我想加入客户的状态,但是如果它 returns NULL 我想给客户部门默认值。我的理想输出如下:
customer_id | department_id | status |
---|---|---|
aaaa | 1234 | silver |
bbbb | 3456 | gold |
我尝试进行两次左连接,但出现内存使用错误。还有其他有效的方法吗?
你可以这样做:
select c.*, coalesce(s.status, d.status) as status
from customers c
left join status d on d.department_id = c.department_id
and d.customer_id is null
left join status s on s.department_id = c.department_id
and s.customer_id = c.customer_id
这可能有效:
SELECT *,
(
SELECT TOP 1 status
FROM status s
WHERE s.customer_id = c.customer_id
OR (c.customer_id IS NULL AND s.department_id = c.department_id)
ORDER BY CASE WHEN s.customer_id is NOT NULL THEN 0 ELSE 1 END
) as status
FROM customers c
关键在于您使用的是哪种数据库。如果是 MySql,您可能需要 LIMIT 1 而不是 TOP 1。对于 Oracle,您需要查看 ROWNUM 字段。
假设至少在 department_id
上始终存在匹配项,您需要一个 INNER
连接并且 FIRST_VALUE()
window 函数将选择正确的 status
:
SELECT DISTINCT
c.customer_id,
c.department_id,
FIRST_VALUE(s.status) OVER (
PARTITION BY c.customer_id, c.department_id
ORDER BY CASE
WHEN s.customer_id = c.customer_id THEN 1
WHEN s.customer_id IS NULL THEN 2
ELSE 3
END
) status
FROM customers c INNER JOIN status s
ON s.department_id = c.department_id;
根据您使用的数据库,代码可能会被简化。
参见demo。