本文的初衷主要是記錄工作中碰到的一些查詢實例,便於后續的工作參考從而提高效率。
一、A表拼接B表的數據,A、B兩個表字段相同,當B表有數據時用B表的,否則用A表的。區分粒度為業務日期。
select z.fundid, z.busidate, z.cloumn1, z.cloumn2 from tablea z where z.fundid in (fundids) and z.busidate between begindate and enddate and z.fundid || z.busidate not in (select t.fundid || t.busidate as unioncode from tableab t group by t.fundid || t.busidate) union select t.fundid, t.busidate, '89' || t.cloumn1, t.cloumn2 from tableab t where t.fundid in(fundids) and t.busidate between begindate and enddate
二、orcal將多條查詢記錄拼接成一條記錄
select listagg(字段名,',') within GROUP(ORDER BY 字段名);
例如,查詢一個表有3條記錄,字段A的值分別是A、B、C。那么使用 listagg 后將返回一條記錄A,B,C
select listagg(fundid || fundname || '(' || alternativelevel || ') ') within GROUP(ORDER BY fundid,fundname,alternativelevel) from zt_alternativefundinfo where fundbankid = z.fundbankid and sysfundid = k.fundid and alternativelevel not in ('B','C')
三、orcal查詢分割字符串
這個跟上面的相反,當一個字段存儲是json格式或是以逗號分開的多個id,對應關聯表的多條數據。我們希望用in 來查詢,返回多條記錄,因此需要分割這個字段的值。
regexp_substr(string, pattern, position, occurrence, modifier) __srcstr :需要進行正則處理的字符串 __pattern :進行匹配的正則表達式 __position :起始位置,從第幾個字符開始正則表達式匹配(默認為1) __occurrence :標識第幾個匹配組,默認為1 __modifier :模式('i'不區分大小寫進行檢索;'c'區分大小寫進行檢索。默認為'c'。)
例如下面的將 '123'拆分成 1、2、3共三條數據
select regexp_substr ('1,2,3', '[^,]+', 1,rownum) from dual connect by rownum<=length ('1,2,3') - length (regexp_replace('1,2,3', ',', ''))+1;
四、not in優化
首先外表大內表小用in,外表小內表大則用exists
1、對於not exists查詢,內表存在空值對查詢結果沒有影響;對於not in查詢,內表存在空值將導致最終的查詢結果為空。
2、對於not exists查詢,外表存在空值,存在空值的那條記錄最終會輸出;對於not in查詢,外表存在空值,存在空值的那條記錄最終將被過濾,其他數據不受影響。
使用 not in 查詢一個結果980萬條的SQL用時3.918s,使用鏈表查詢則用時3.622s多,測試了很多次鏈表確實比not in快一點
-- not in 3.918s select * FROM tablea WHERE .. . AND id not in (select id from tableb); -- left 3.622s select a.* FROM tablea a left join tableb on a.id = b.id WHERE .. . AND a.id is null;