如何简化含重复INNER JOIN关联逻辑的SQL查询语句
SQL冗余查询优化方案
你当前使用的多个相关子查询存在两个核心问题:一是相同的多表关联、筛选条件重复编写,代码冗余度极高;二是每生成一个Flight列就会重复执行一次表关联扫描,列数越多性能损耗越严重。
可以通过「单次关联取数+窗口函数编号+条件聚合行转列」的思路简化,全程只需要编写一次关联逻辑,从根源上消除重复代码。
优化后SQL代码
WITH FlightCTE AS ( SELECT bp.BookingID, CONCAT(il.CCode, il.FlightNumber, ';', dc.[Name]) AS FlightInfo, -- 按每个订单下的航班STD时间升序编号,从1开始 ROW_NUMBER() OVER (PARTITION BY bp.BookingID ORDER BY il.STD) AS FlightSeq FROM ILeg il INNER JOIN PLeg pjl ON pjl.InventoryLegID = il.InventoryLegID INNER JOIN PSegment pjs ON pjs.SegmentID = pjl.SegmentID INNER JOIN BPassenger bp ON bp.PassengerID = pjs.PassengerID INNER JOIN City dc ON dc.CityCode = il.DepartureStation WHERE il.CarrierCode = '12T' ) SELECT b.BookingID, MAX(CASE WHEN fc.FlightSeq = 1 THEN fc.FlightInfo END) AS Flight1, MAX(CASE WHEN fc.FlightSeq = 2 THEN fc.FlightInfo END) AS Flight2, MAX(CASE WHEN fc.FlightSeq = 3 THEN fc.FlightInfo END) AS Flight3 -- 如需新增Flight4、Flight5列,直接复制上面行修改序号和别名即可,无需重复写关联逻辑 FROM Booking b LEFT JOIN FlightCTE fc ON b.BookingID = fc.BookingID WHERE b.RecordLocator = '1234' GROUP BY b.BookingID
优化说明
- 所有多表关联、筛选逻辑只在CTE中编写一次,代码冗余度大幅降低,后续维护只需要修改一处逻辑
- 原查询中关联的到达城市表
ac没有被任何字段使用,属于无效关联,优化时直接移除,减少不必要的查询开销 - 修正了原SQL中Flight2、Flight3字段
CONCAT函数多写左括号的语法错误 - 相比原相关子查询写法,多表关联扫描只执行一次,航班列越多性能提升越明显
- 扩展列的成本极低,不需要重复编写长串关联、筛选逻辑
- 使用LEFT JOIN关联航班数据,避免某个序号的航班不存在时出现子查询异常
内容的提问来源于stack exchange,提问作者sThirumagal93
相关产品推荐
相关产品推荐

