You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Oracle SQL Developer查询改写为SQL Server多表左连接求助

如何将Oracle(+)外连接改写为SQL Server的多表左连接

刚从Oracle转到SQL Server确实会遇到语法适配的问题,Oracle的(+)外连接语法在SQL Server里不被支持,不过我们可以用标准的LEFT JOIN(和LEFT OUTER JOIN等价,SQL Server中两者通用)来实现完全相同的逻辑。

先拆解你的原Oracle查询:核心是主表DTE24左连接三个聚合子查询totaaltotaal1totaal2,连接条件是CONTROLEWAARDEBEG字段匹配。下面是改写后的SQL Server兼容版本:

SELECT DISTINCT
    DTE24.CONDSRT,
    DTE24.CONTROLE,
    DTE24.WAARDEBEG,
    totaal.totaalx,
    totaal1.totaalof1,
    totaal2.totaalof2
FROM [RT_IPOIKAZ_ODS].[WinIKAZ].[DTE24]
LEFT JOIN (
    SELECT 
        CONTROLE, 
        WAARDEBEG, 
        COUNT(WAARDEBEG) AS totaalx
    FROM [RT_IPOIKAZ_ODS].[WinIKAZ].[DTE24]
    WHERE CONTROLE = 12885 
      AND DATAFVOER = 0 
      AND CONDSRT = 'PRESCODE' 
      AND OFNIVO IN (1,2)
    GROUP BY CONTROLE, WAARDEBEG
) AS totaal 
    ON DTE24.CONTROLE = totaal.CONTROLE 
    AND DTE24.WAARDEBEG = totaal.WAARDEBEG
LEFT JOIN (
    SELECT 
        CONTROLE, 
        WAARDEBEG, 
        COUNT(WAARDEBEG) AS totaalof1
    FROM [RT_IPOIKAZ_ODS].[WinIKAZ].[DTE24]
    WHERE CONTROLE = 12885 
      AND DATAFVOER = 0 
      AND CONDSRT = 'PRESCODE' 
      AND OFNIVO = 1
    GROUP BY CONTROLE, WAARDEBEG
) AS totaal1 
    ON DTE24.CONTROLE = totaal1.CONTROLE 
    AND DTE24.WAARDEBEG = totaal1.WAARDEBEG
LEFT JOIN (
    SELECT 
        CONTROLE, 
        WAARDEBEG, 
        COUNT(WAARDEBEG) AS totaalof2
    FROM [RT_IPOIKAZ_ODS].[WinIKAZ].[DTE24]
    WHERE CONTROLE = 12885 
      AND DATAFVOER = 0 
      AND CONDSRT = 'PRESCODE' 
      AND OFNIVO = 2
    GROUP BY CONTROLE, WAARDEBEG
) AS totaal2 
    ON DTE24.CONTROLE = totaal2.CONTROLE 
    AND DTE24.WAARDEBEG = totaal2.WAARDEBEG
WHERE DTE24.CONTROLE = 12885 
  AND DTE24.DATAFVOER = 0 
  AND DTE24.CONDSRT = 'PRESCODE'
ORDER BY DTE24.WAARDEBEG;

关键改写点说明:

  • 替换(+)为LEFT JOIN:Oracle中DTE24.WAARDEBEG = totaal.WAARDEBEG(+)等价于SQL Server的DTE24 LEFT JOIN totaal ON DTE24.WAARDEBEG = totaal.WAARDEBEG,这样主表DTE24的所有符合条件的行都会被保留,即使子查询中没有匹配的记录,对应的聚合字段会显示为NULL
  • 明确连接条件:每个LEFT JOIN都单独指定连接的字段(CONTROLEWAARDEBEG),这比Oracle的隐式连接写法更清晰,也符合SQL标准。
  • 补全主表过滤条件:我给主表DTE24加上了和子查询一致的过滤条件,这能确保你拿到的数据集和原Oracle查询逻辑完全一致——原Oracle查询里虽然没写主表的这些过滤,但子查询的条件加上连接关系,其实隐含了主表的这些过滤,明确写出来更直观。
  • ORDER BY优化:把原查询的ORDER BY 3改成了ORDER BY DTE24.WAARDEBEG,用列名排序比用位置更易读,也避免后续修改列顺序时出错。

如果运行后有聚合结果不符合预期的情况,可以检查子查询的过滤条件是否和原Oracle一致,或者主表的过滤是否正确。

内容的提问来源于stack exchange,提问作者NiekP

火山引擎 最新活动