sql技巧:兩表關聯不同情況關聯不同字段


環境:MYSQL

問題描述:表A和表B關聯,關聯字段有cat1、cat2、cat3三個維度;表A是配置表,三個字段肯定有值,表B是事實表,三個字段不一定都有值,但是如果cat2有,則cat1肯定有,以此類推;

需求:將表A和表B關聯,如果表B的cat3為空,則用cat1和cat2字段關聯,如果cat2為空,則用cat1關聯,以此類推。

use mytest;
-- 數據准備
create table mycat01 (
	cat1 varchar(10),
    cat2 varchar(10),
    cat3 varchar(10),
    val1 int
);

create table mycat02 (
	cat1 varchar(10),
    cat2 varchar(10),
    cat3 varchar(10),
    val1 int
);


insert into mycat01
values('100', '100-100', '100-100-1',22);
insert into mycat01
values('100', '100-200', '100-200-1',33);
insert into mycat01
values('200', '200-100', '200-100-1',44);


insert into mycat02
values('100', '100-100', '100-100-1',22);
insert into mycat02
values('100', '100-200', null,66);
insert into mycat02
values('200', null, null,88);

-- 直接關聯:會出現缺失
select a.*, b.cat1 
from mycat01 a 
left join mycat02 b on a.cat1=b.cat1 and a.cat2=b.cat2 and a.cat3=b.cat3;

-- 解法1:寫多個left join; 優點:可讀性強;缺點:重復性高,left join次數多執行效率低。
select  a.*, b1.*, b2.*, b3.* 
from mycat02 a 
left join  mycat01 b1 on a.cat1 is not null and a.cat2 is not null and a.cat3 is not null
	and a.cat1=b1.cat1 and a.cat2=b1.cat2 and a.cat3=b1.cat3
left join  mycat01 b2 on a.cat1 is not null and a.cat2 is not null and a.cat3 is null
	and a.cat1=b2.cat1 and a.cat2=b2.cat2 -- and a.cat3=b.cat3
left join  mycat01 b3 on a.cat1 is not null and a.cat2 is null and a.cat3 is null
	and a.cat1=b3.cat1; -- and a.cat2=b.cat2 and a.cat3=b.cat3;


-- 解法2:將cat1-3拼起來,然后用like關聯。
-- 把mycat01當做主表 
select a.*, b.cat_full, b.val1
from (select concat(cat1, '_', cat2, '_', cat3) as cat_full, val1 from mycat01) a 
left join (
	select concat(cat1, '_'
			, if(coalesce(cat2,'')<>'', concat(cat2, '_'),'')
			, coalesce(cat3,'')
        ) as cat_full
        , val1 
	from mycat02
) b on a.cat_full like concat(b.cat_full,'%'); -- 也可以用 locate(b.cat_full,a.cat_full)=1

-- 如果 mycat02是主表,left join左右對換也同樣適用 
select b.*, a.cat_full, a.val1
from (
	select concat(cat1, '_'
			, if(coalesce(cat2,''), concat(cat2, '_'),'')
			, coalesce(cat3,'')
        ) as cat_full
        , val1 
	from mycat02
) a 
left join (
	select concat(cat1, '_', cat2, '_', cat3) as cat_full, val1 from mycat01
) b on b.cat_full like concat(a.cat_full,'%');

補充: 如果在Hive里,就不支持join...on里用like做關聯,改用locate(),具體見上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM