简体   繁体   English

加入两列,如果 null 则只加入一列

[英]Join on two columns, if null then only join on one

I have the following two tables:我有以下两个表:

customers:顾客:

customer_id客户ID department_id部门编号
aaaa啊啊啊 1234 1234
bbbb bbbb 3456 3456

status:地位:

department_id部门编号 customer_id客户ID status地位
1234 1234 NULL NULL silver
3456 3456 bbbb bbbb gold金子
1234 1234 bbbb bbbb gold金子

I want to join status on customers, but if if it returns NULL I want to give the customer the department default.我想加入客户状态,但如果它返回 NULL 我想给客户部门默认值。 My ideal Output for this would be the following:我理想的 Output 如下:

customer_id客户ID department_id部门编号 status地位
aaaa啊啊啊 1234 1234 silver
bbbb bbbb 3456 3456 gold金子

I have tried to do two left joins, but am getting a memory usage error.我尝试执行两个左连接,但出现 memory 使用错误。 Is there another way to do this that is efficient?还有另一种有效的方法吗?

You can do:你可以做:

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

This might work:这可能有效:

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

The kicker is what kind of database you're using.问题在于您使用的是哪种数据库。 If it's MySql you might want LIMIT 1 instead of TOP 1. For Oracle you'd look at the ROWNUM field.如果它是 MySql,您可能需要 LIMIT 1 而不是 TOP 1。对于 Oracle,您需要查看 ROWNUM 字段。

Assuming that there is always a match at least on the department_id , you need an INNER join and FIRST_VALUE() window function will pick the proper status :假设至少在department_id上总有一个匹配项,您需要一个INNER连接并且FIRST_VALUE() window function 将选择正确的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;

Depending on the database that you use the code may be simplified.根据您使用的数据库,代码可能会被简化。

See the demo .请参阅演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM