left join的多重串联与groupby

本文介绍了一个具体的SQL查询案例,通过使用左连接(left join)和分组(group by)来整合三个表中的信息。主要针对表间一对多的关系进行数据整合,展示了如何在一个查询中同时处理多个关联表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有三张表或组合查询,f1,f2,f3,其中,f1分别与f2,f3是一对多关系,f1一条记录可能对应f2或f3中0条或多条记录

要创建一个查询,以f1为基准,即f1中有多少条记录,结果也就返回对应数量的记录,并整合f2,f3中的相应信息

此时需要创建两个left join 串接并加上group by如:

有三张表或组合查询,f1,f2,f3,其中,f1分别与f2,f3是一对多关系,f1一条记录可能对应f2或f3中0条或多条记录 

要创建一个查询,以f1为基准,即f1中有多少条记录,结果也就返回对应数量的记录,并整合f2,f3中的相应信息 

此时需要创建两个left join 串接并加上group by如: 

select f1.x,f1.y,max(f2.b),wmsys.wm_concat(f3.c)

from

(.........

) f1

left join

(........

) f2

on f1.z=f2.k

left join

(........

) f3

on f1.z=f3.c

group by f1.x,f1.y

 

实例

select f1.pro_uuid,f1.程序类型,f1.程序名,f1.过渡名,f1.航线类型,f1.航线限定1,f1.航线限定2, f1.机型限制

,wmsys.wm_concat(nvl2(f2.page,f1.ad||'-'||f2.page,null)) 航图, wmsys.wm_concat(f2.nav_source) 导航源

,wmsys.wm_concat(distinct nvl2(f3.rrwd,'RW'||f3.rrwd,null)) 跑道

from

(

select d.procedure_uuid pro_uuid,a.designator ad,

decode(d.PRO_TYPE,'SID','离场','STAR','进场','IAP','进近',PRO_TYPE) 程序类型,

d.PRO_NAME 程序名,

d.TRANS_IDEN 过渡名,

d.route_type||' '||(select name from TERMPRO_RULE_ROUTE_TYPE where protype=d.pro_type and routetype=d.route_type) 航线类型,

d.qulifier_1||' '||(select QUALIFIERNAME from TERMPRO_RULE_ROUTE_QUALIFIER where QUALIFIER=d.qulifier_1 and ONE_OR_TWO=1) 航线限定1,

d.qulifier_2||' '||(select QUALIFIERNAME from TERMPRO_RULE_ROUTE_QUALIFIER where QUALIFIER=d.qulifier_2 and ONE_OR_TWO=2) 航线限定2,

decode(acft_cat,'P',null,(select name from RULE_ACFT_CAT where CODE_ACFT_CAT= d.acft_cat)) 机型限制

from TERMINAL_PROCEDURE_TS d,airport_heliport_ts a

where d.airport_heliport_uuid='4a4ea52d-69be-48e4-baa1-321ee6d023d7'

and d.airport_heliport_uuid=a.airport_heliport_uuid

and vernumber(a.eff_version_id)<=201799 and vernumber(a.out_version_id)>201799 and d.interpretation='BASELINE'

and vernumber(d.eff_version_id)<=201799 and vernumber(d.out_version_id)>201799 and d.interpretation='BASELINE'

) f1

left join

(

select pc.procedure_uuid pro_uuid, c.page_number page, tc.type_name nav_source 

from terminal_chart_ts c, termpro_chart_ts pc, terminal_chart_type tc

where pc.chart_uuid=c.terminal_chart_uuid

and c.sub_chart_type_id=tc.chart_type_id

and vernumber(c.eff_version_id)<=201799 and vernumber(c.out_version_id)>201799 and c.interpretation='BASELINE'

and vernumber(pc.eff_version_id)<=201799 and vernumber(pc.out_version_id)>201799 and pc.interpretation='BASELINE'

) f2

on f1.pro_uuid=f2.pro_uuid

left join

(

select pw.procedure_uuid pro_uuid, rd.designator rrwd

from TERMPRO_RWYDRC_TS pw, runway_direction_ts rd

where pw.runway_direction_uuid=rd.runway_direction_uuid

and vernumber(pw.eff_version_id)<=201799 and vernumber(pw.out_version_id)>201799 and pw.interpretation='BASELINE'

and vernumber(rd.eff_version_id)<=201799 and vernumber(rd.out_version_id)>201799 and rd.interpretation='BASELINE'

) f3

on f1.pro_uuid=f3.pro_uuid

group by f1.pro_uuid,f1.程序类型,f1.程序名,f1.过渡名,f1.航线类型,f1.航线限定1,f1.航线限定2, f1.机型限制

order by decode(f1.程序类型,'离场',1,'进场',2,'进近',3),f1.程序名,f1.过渡名

转载于:https://www.cnblogs.com/mol1995/p/7852137.html

我在使用fdl的时候,数据来源代码为 -- 定义动态日期范围 DECLARE @EndDate DATE = GETDATE(); DECLARE @StartDate DATE = DATEADD(DAY, -365, @EndDate); -- 创建部门临时表 IF OBJECT_ID('tempdb..#TEMP_Department') IS NOT NULL DROP TABLE #TEMP_Department; CREATE TABLE #TEMP_Department (Department nvarchar(20)); INSERT INTO #TEMP_Department EXEC [ZY_P_Get_SAP_Account_to_TempDept]; -- 基础销售额计算 IF OBJECT_ID('tempdb..#Sales') IS NOT NULL DROP TABLE #Sales; SELECT T.客户名称, SUM(T.RMB总价) AS 销售额 INTO #Sales FROM [ZY_TB_SALES_Details] T INNER JOIN #TEMP_Department D ON T.综合部门 = D.Department WHERE T.交货日期 BETWEEN @StartDate AND @EndDate AND T.业务体系 = '经销体系' GROUP BY T.客户名称; -- 1. 计算总毛利(非项目+项目) IF OBJECT_ID('tempdb..#NonProjectProfit') IS NOT NULL DROP TABLE #NonProjectProfit; SELECT T.客户名称, SUM(T.扣技服后毛利) AS 非项目毛利 INTO #NonProjectProfit FROM [ZY_TB_SALES_Details] T INNER JOIN #TEMP_Department D ON T.综合部门 = D.Department WHERE T.交货日期 BETWEEN @StartDate AND @EndDate AND T.业务体系 = '经销体系' AND T.项目合同YN IS NULL GROUP BY T.客户名称; IF OBJECT_ID('tempdb..#ProjectProfit') IS NOT NULL DROP TABLE #ProjectProfit; SELECT 客户名称, SUM(有效综合毛利RMB) AS 项目毛利 INTO #ProjectProfit FROM ZY_TB_JX_XM_SalesPer_Profit WHERE 交货日期 BETWEEN @StartDate AND @EndDate AND 综合部门 IN (SELECT Department FROM #TEMP_Department) GROUP BY 客户名称; IF OBJECT_ID('tempdb..#ProfitScore') IS NOT NULL DROP TABLE #ProfitScore; SELECT COALESCE(N.客户名称, P.客户名称) AS 客户名称, ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) AS 总毛利, CASE WHEN ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) >= 1000000 THEN 100 WHEN ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) >= 500000 THEN 80 WHEN ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) >= 100000 THEN 60 WHEN ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) >= 10000 THEN 40 WHEN ISNULL(N.非项目毛利, 0) + ISNULL(P.项目毛利, 0) > 0 THEN 20 ELSE 0 END * 0.3 AS 毛利得分 INTO #ProfitScore FROM #NonProjectProfit N FULL OUTER JOIN #ProjectProfit P ON N.客户名称 = P.客户名称; -- 2. 计算预收款 IF OBJECT_ID('tempdb..#Advance') IS NOT NULL DROP TABLE #Advance; WITH CTE_OACT AS (SELECT AcctCode, AcctName FROM OACT), CTE_BANK AS ( SELECT DISTINCT Number AS '进账单流水号', BankName AS '银行信息' FROM [WEB_BANKINCOME] UNION ALL SELECT 到帐单流水号 AS '进账单流水号', 银行信息 FROM [ZY_TB_WEB_BANKINCOME_OLD] ), CTE_Result AS ( SELECT T0.CardName AS N'客户名称', T0.OpenBal AS N'未清金额', T0.Canceled FROM ORCT T0 INNER JOIN CTE_OACT t3 ON t0.TrsfrAcct = t3.AcctCode LEFT JOIN (SELECT DISTINCT 进账单流水号, 银行信息 FROM CTE_BANK) M0 ON M0.进账单流水号 = T0.U_LSH LEFT JOIN [ZY_VIEW_XM] X0 ON X0.ConCode = T0.U_contractnumber LEFT JOIN OCRD d1 ON d1.CardCode = t0.CardCode WHERE T0.taxdate<= @EndDate AND T0.U_Department IN ('上海办','生命科学部','分销部','工业部','天津办','基础科研部','沈阳办','烟台办','广州办','成都办','商务部') ) SELECT [客户名称], SUM(CASE WHEN Canceled = 'N' THEN [未清金额] ELSE 0 END) AS 预收款金额 INTO #Advance FROM CTE_Result GROUP BY [客户名称]; -- 3. 计算应收款和超期应收款 IF OBJECT_ID('tempdb..#OverdueBase') IS NOT NULL DROP TABLE #OverdueBase; SELECT T.客户名称, T.未收款金额, ISNULL(X.XM_YN, 'N') AS 项目合同, T.DN日期 AS 销货日期, T.业务体系 INTO #OverdueBase FROM [ZY_TB_Receivable_Balance_Base] T INNER JOIN #TEMP_Department X0 ON X0.Department = T.综合部门 LEFT JOIN [ZY_VIEW_XM] X ON X.ConCode = T.合同号 WHERE T.业务体系 = '经销体系'; -- 完整应收款 (用于展示) IF OBJECT_ID('tempdb..#TotalReceivable') IS NOT NULL DROP TABLE #TotalReceivable; SELECT 客户名称, SUM(未收款金额) AS 应收款总额 INTO #TotalReceivable FROM #OverdueBase WHERE 项目合同 = 'N' GROUP BY 客户名称; -- 超期应收款 (用于得分计算) IF OBJECT_ID('tempdb..#Overdue') IS NOT NULL DROP TABLE #Overdue; SELECT 客户名称, SUM(未收款金额) AS 超期应收款 INTO #Overdue FROM #OverdueBase WHERE 项目合同 = 'N' AND DATEDIFF(DAY, 销货日期, @EndDate) >= 180 GROUP BY 客户名称; -- 4. 计算库存 -- 完整库存 (用于展示) IF OBJECT_ID('tempdb..#TotalInventory') IS NOT NULL DROP TABLE #TotalInventory; SELECT [客户名称], SUM([含税总价RMB]) AS 库存总额 INTO #TotalInventory FROM ( SELECT R0.CardName AS '客户名称', CASE WHEN A0.U_CustomsRate IS NOT NULL THEN CASE WHEN A0.U_Import ='Y' AND A0.U_RevisedDuty IS NOT NULL THEN (A0.U_ForeignPrice * A0.U_CustomsRate + ISNULL(A0.U_RevisedDuty,0)) * (A0.U_InputVATRate/100+1) WHEN A0.U_Import ='Y' AND A0.U_RevisedDuty IS NULL THEN (A0.U_PriceAfVAT + ISNULL(A0.U_Tariff,0)) * (A0.U_InputVATRate/100+1) ELSE (A0.U_PriceAfVAT + ISNULL(A0.U_Tariff,0)) END * B0.Quantity ELSE CASE WHEN A0.U_Import ='Y' THEN (A0.U_PriceAfVAT + ISNULL(A0.U_Tariff,0)) * (A0.U_InputVATRate/100+1) ELSE (A0.U_PriceAfVAT + ISNULL(A0.U_Tariff,0)) END * B0.Quantity END AS '含税总价RMB' FROM OBTN A0 JOIN OIBT B0 ON B0.ItemCode = A0.ItemCode AND B0.BatchNum = A0.DistNumber AND B0.SysNumber = A0.SysNumber LEFT JOIN ORDR R0 ON R0.SupplCode = A0.U_SaleContNo WHERE B0.Quantity > 0 AND R0.CardName IS NOT NULL ) AS SubQuery GROUP BY [客户名称]; -- 5. 获取客户主数据 IF OBJECT_ID('tempdb..#CustomerMaster') IS NOT NULL DROP TABLE #CustomerMaster; SELECT CardCode AS 客户编号, CardName AS 客户名称, CASE WHEN UPPER(ISNULL(cntctprsn, '')) = 'VIP' THEN 'VIP' ELSE '' END AS 客户类型 INTO #CustomerMaster FROM OCRD WHERE Cardtype = 'C'; -- 6. 创建主客户表 IF OBJECT_ID('tempdb..#MasterClient') IS NOT NULL DROP TABLE #MasterClient; SELECT CM.客户编号, CM.客户类型, CM.客户名称, ISNULL(P.总毛利, 0) AS 近期毛利, ISNULL(P.毛利得分, 0) AS 毛利得分, ISNULL(A.预收款金额, 0) AS 预收款金额, ISNULL(R.应收款总额, 0) AS 应收款总额, ISNULL(TI.库存总额, 0) AS 库存总额, ISNULL(O.超期应收款, 0) AS 超期应收款 INTO #MasterClient FROM #CustomerMaster CM LEFT JOIN #ProfitScore P ON CM.客户名称 = P.客户名称 LEFT JOIN #Advance A ON CM.客户名称 = A.客户名称 LEFT JOIN #TotalReceivable R ON CM.客户名称 = R.客户名称 LEFT JOIN #TotalInventory TI ON CM.客户名称 = TI.客户名称 LEFT JOIN #Overdue O ON CM.客户名称 = O.客户名称; -- 7. 计算得分 (修复列不明确问题) IF OBJECT_ID('tempdb..#Scores') IS NOT NULL DROP TABLE #Scores; SELECT MC.客户名称, -- 明确指定使用#MasterClient表的客户名称 -- 预收款得分 (ISNULL(预收款占比得分, 0) + ISNULL(预收款金额得分, 0)) / 2 * 0.2 AS 预收款得分, -- 超期应收款得分 (ISNULL(超期占比得分, 100) + ISNULL(超期金额得分, 100)) / 2 * 0.3 AS 超期得分, -- 库存得分 CASE WHEN ISNULL(库存占比得分, 100) < ISNULL(库存金额得分, 100) THEN ISNULL(库存占比得分, 100) ELSE ISNULL(库存金额得分, 100) END * 0.2 AS 库存得分 INTO #Scores FROM #MasterClient MC LEFT JOIN #Sales S ON MC.客户名称 = S.客户名称 CROSS APPLY ( SELECT -- 预收款得分计算 CASE WHEN 预收款金额 / NULLIF(S.销售额, 0) >= 1 THEN 100 WHEN 预收款金额 / NULLIF(S.销售额, 0) >= 0.5 THEN 75 WHEN 预收款金额 / NULLIF(S.销售额, 0) >= 0.1 THEN 50 WHEN 预收款金额 > 0 THEN 25 ELSE 0 END AS 预收款占比得分, CASE WHEN 预收款金额 >= 1000000 THEN 100 WHEN 预收款金额 >= 500000 THEN 75 WHEN 预收款金额 >= 100000 THEN 50 WHEN 预收款金额 > 0 THEN 25 ELSE 0 END AS 预收款金额得分, -- 超期应收款得分计算 CASE WHEN 超期应收款 / NULLIF(S.销售额, 0) >= 1 THEN 0 WHEN 超期应收款 / NULLIF(S.销售额, 0) >= 0.5 THEN 25 WHEN 超期应收款 / NULLIF(S.销售额, 0) >= 0.1 THEN 50 WHEN 超期应收款 > 0 THEN 75 ELSE 100 END AS 超期占比得分, CASE WHEN 超期应收款 >= 1000000 THEN 0 WHEN 超期应收款 >= 500000 THEN 25 WHEN 超期应收款 >= 100000 THEN 50 WHEN 超期应收款 > 0 THEN 75 ELSE 100 END AS 超期金额得分, -- 库存得分计算 CASE WHEN 库存总额 / NULLIF(S.销售额, 0) >= 1 THEN 0 WHEN 库存总额 / NULLIF(S.销售额, 0) >= 0.5 THEN 25 WHEN 库存总额 / NULLIF(S.销售额, 0) >= 0.1 THEN 50 WHEN 库存总额 > 0 THEN 75 ELSE 100 END AS 库存占比得分, CASE WHEN 库存总额 >= 1000000 THEN 0 WHEN 库存总额 >= 500000 THEN 25 WHEN 库存总额 >= 100000 THEN 50 WHEN 库存总额 > 0 THEN 75 ELSE 100 END AS 库存金额得分 ) AS Scores; -- 8. 汇总最终结果 SELECT MC.客户编号, MC.客户类型, MC.客户名称, ROUND( ISNULL(MC.毛利得分, 0) + ISNULL(S.预收款得分, 0) + ISNULL(S.超期得分, 0) + ISNULL(S.库存得分, 0), 2) AS 用户评级, MC.应收款总额 AS 应收款, MC.预收款金额 AS 预收款, MC.库存总额 AS 专项库存, MC.近期毛利 AS 近期毛利, '' AS 备注2 FROM #MasterClient MC LEFT JOIN #Scores S ON MC.客户名称 = S.客户名称 ORDER BY 用户评级 DESC; -- 清理所有临时表 DROP TABLE #Sales, #NonProjectProfit, #ProjectProfit, #ProfitScore, #Advance, #TEMP_Department, #OverdueBase, #Overdue, #CustomerMaster, #MasterClient, #TotalReceivable, #TotalInventory, #Scores; 然后报错了com.fr.dp.exception.FineDPException: 数据连接异常 - DataBase[sino_sap] get column failed - SQL语句包含非法字符 - JDBC SQL校验语句中出现了不被允许的关键字: create
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值