加入两列,如果为空则只加入一列

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