oracle的多表合併查詢-工作心得
本隨筆文章,由個人博客(鳥不拉屎)轉移至博客園
發佈時間: 2018 年 11 月 29 日
原地址:https://niaobulashi.com/archives/oracle-select-all.html
剛剛開發需求寫了個SQL,記個筆記,學習下關於數據庫的多表合併查詢的用法
select t.* from A t
UNION ALL/UNION/Intersect/MINUS
select s.* from B s;
UNION ALL
使用UNION ALL,表示取A、B的合集,不過濾重複的數據行
UNION
使用UNION,會將結果集A和結果集B進行UNION ALL運算,然後取兩者交集的餘集作爲結果集
Intersect
使用Intersect,會將結果集A和結果集B進行UNION ALL運算,然後兩者之間的集交集作爲結果集和UNION剛好相反
MINUS
使用MINUS,取結果集A減去結果集B留下的差集,注:如果結果集A小於等於結果集B,返回空結果集.
好啦,下面進入實戰階段,我就直接將我寫的SQL貼出來吧
select a.*
from (select t.c_fund_account_name as "fundAccountNo", --基金賬號
tfp.project_code as "projectCode", --項目編號
tfp.project_name as "projectName", --項目名稱
tfp.project_shortname as "projectShortName", --項目簡稱
c.c_fund_name as "fundName", --基金產品名稱
c.c_fund_code as "fundCode", --基金產品代碼
nvl(thold.subsistAssetsShare, 0) as "subsisAssetsShare", --份額(家族)
to_char(thold.updateDate, 'yyyy-MM-dd') as "updateDate", --日期
nvl(c.c_current_share, 0) as "currentShare", --份額(基金網站)
to_char(c.d_date, 'yyyy-MM-dd') as "dateDate", --日期
(nvl(thold.subsistAssetsShare, 0) - nvl(c.c_current_share, 0)) as "diffValue", --差值
CAST((CASE
WHEN (nvl(thold.subsistAssetsShare, 0) -
nvl(c.c_current_share, 0)) = 0 THEN
'1'
WHEN (nvl(thold.subsistAssetsShare, 0) -
nvl(c.c_current_share, 0)) <> 0 THEN
'0'
END) as nvarchar2(2)) as "identical" --是否一致
from t_fund_account t
inner join (select fhs.*,
row_number() over(partition by fhs.c_fund_account_no, fhs.c_project_code order by fhs.d_date desc) rn
from td_fund_holding_share fhs) c
on t.c_fund_account_name = c.c_fund_account_no
and t.c_project_code = c.c_project_code
LEFT JOIN (SELECT tha.project_code as projectCode,
sum(tha.current_share) as subsistAssetsShare, -- 持有份額
sum(tha.current_cost) as currentCost, --當前成本
sum(tha.accumulated_profit) as accumulatedProfit, --累積利潤
max(tha.update_time) as updateDate
FROM t_hold_assets tha
left join t_polling_product p
on tha.c_product_code = p.c_product_code
WHERE 1 = 1
and tha.delete_flag = '0'
and p.c_stock_type_level1 = '0'
and p.c_stock_type_level2 = '01'
GROUP BY tha.project_code) thold
on thold.projectCode = t.c_project_code
left join t_family_project tfp
on tfp.project_code = t.c_project_code
and tfp.delete_flag = '0'
where rn = 1
AND t.c_fund_account_type = '1' --基金賬戶
AND t.delete_flag = '0'
UNION ALL
select t.c_fund_account_name as "fundAccountNo", --基金賬號
tfp.project_code as "projectCode", --項目編號
tfp.project_name as "projectName", --項目名稱
tfp.project_shortname as "projectShortName", --項目簡稱
CAST('' as nvarchar2(50)) as "fundName", --基金產品名稱
CAST('' as nvarchar2(50)) as "fundCode", --基金產品代碼
nvl(thold.subsistAssetsShare, 0) as "subsisAssetsShare", --份額(家族)
to_char(thold.updateDate, 'yyyy-MM-dd') as "updateDate", --日期
to_number(nvl('', 0)) as "currentShare", --份額(基金網站)
to_char(CAST('' as nvarchar2(50)), 'yyyy-MM-dd') as "dateDate", --日期
nvl(thold.subsistAssetsShare, 0) - nvl('', 0) as "diffValue", --差值
CAST((CASE
WHEN (nvl(thold.subsistAssetsShare, 0) - nvl('', 0)) = 0 THEN
'1'
WHEN (nvl(thold.subsistAssetsShare, 0) - nvl('', 0)) <> 0 THEN
'0'
END) as nvarchar2(2)) as "identical" --是否一致
from t_fund_account t
LEFT JOIN (SELECT tha.project_code as projectCode,
sum(tha.current_share) as subsistAssetsShare, -- 持有份額
max(tha.update_time) as updateDate
FROM t_hold_assets tha
left join t_polling_product p
on tha.c_product_code = p.c_product_code
WHERE 1 = 1
and tha.delete_flag = '0'
and p.c_stock_type_level1 = '0'
and p.c_stock_type_level2 = '01'
GROUP BY tha.project_code) thold
on thold.projectCode = t.c_project_code
left join t_family_project tfp
on t.c_project_code = tfp.project_code
and tfp.delete_flag = '0'
where t.c_fund_account_name not in
(select td.c_fund_account_no from td_fund_holding_share td)
and t.c_fund_account_type = '1'
and t.delete_flag = '0') a
order by a."diffValue" desc, a."projectCode" desc
上面sql具體意思是:查詢出基金信息,A和基金對比先查詢其中有的數據,再union all A有基金沒有的數據,一起取個並集。OK,需求完成
哈哈哈哈,其實只要你SQL寫得牛逼,然後瞭解下業務流程,什麼都好說哈哈哈
哦對了,最後囉嗦一句。 對於這些並集計算之後,需要排序 則語法爲:
select t.* from (語句1 union all 語句2)
t order by t.id;