加入CASE或其他替代方案(MySQL)

时间:2016-08-10 13:34:05

标签: mysql sql if-statement join case

我需要加入2个表。 表1:

User |Country|
--------------
 a   |  NZ   |
 a   |  NZ   |
 a   |  HU   |
 a   |  IL   |
 a   |  AU   |
 a   |  AU   |
 a   |  RO   |
 a   |  NZ   |
 a   |  NZ   | 
 a   |  NZ   |
 a   |  GB   |
 a   |  GB   |

表2:

   User  |Country| Payment
    ----------------------
     a   |   GB  |  20
     a   |   AU  |  20
     a   |       |  30

我想得到的最终结果就是这个:

User | Country | Payment
--------------
 a   |   NZ    |   30
 a   |   NZ    |   30
 a   |   HU    |   30
 a   |   IL    |   30
 a   |   AU    |   20
 a   |   AU    |   20
 a   |   RO    |   30
 a   |   NZ    |   30
 a   |   NZ    |   30
 a   |   NZ    |   30
 a   |   GB    |   20
 a   |   GB    |   20

结果有两个条件:

1 - 如果两个表中的国家/地区相同,则给我相应的付款,即在这种情况下仅为GB和AU。

2 - 如果表2中的国家/地区为NULL,则将付款加入所有其他国家/地区(GB和AU除外)

这个东西可以通过2个左连接完成,但有没有办法用1做?像CASE / IF这样的东西。我看了几个加入CASE的例子,但它不适合我。

感谢。

3 个答案:

答案 0 :(得分:1)

这是你想要“默认”的地方。 left join很方便,实际上是两个。第一次与国家完全匹配;第二个带来NULL值。

select t1.*, coalesce(t2.payment, t2d.payment) as payment
from t1 left join
     t2 t2
     on t1.country = t2.country left join
     t2 t2d
     on t2d.country is null;

这是解决问题的最佳方法,因为它可以在t2(country)上使用索引。

还有其他方法;例如:

select t1.*
       (select t2.payment
        from t2
        where t2.country = t.country or t2.country is null
        order by (t2.country is not null) desc
       ) as payment
from t;

或者,您可以使用一个显式join和聚合。或者像这样繁琐的东西:

select t1.*, t2.payment
from t1 join
     t2
     on t1.country = t2.country
union all
select t1.*, t2.payment
from t1 join
     t2
     on t2.country is null
where t.country not in (select t2.country from t2 where t2.country is not null);

但是有两个left join s的版本是最好的方法。

答案 1 :(得分:1)

虽然我认为2 outer joins会更有效率,因为您只想使用单个join,这里有一个使用子查询和conditional aggregation的选项:

select usr, country, coalesce(payment, defaultpayment) as payment
from (
    select t1.usr, t1.country, 
        max(case when t1.country = t2.country then payment end) payment,
        max(case when t2.country is null then payment end) defaultpayment
    from t1
       left join t2 on t1.usr = t2.usr 
    group by t1.usr, t1.country 
) t

答案 2 :(得分:0)

我的解决方案就是这个:

LEFT JOIN国家b ON INSTR(a.geo,b.Code)<> 0

因此只有在实例匹配时才可以使用JOIN。