【问题标题】:Assistance replacing oracle (+) joins to ANSI joins协助将 oracle (+) 连接替换为 ANSI 连接
【发布时间】:2015-11-06 12:03:08
【问题描述】:

我查看了其他帖子以及有关用 ANSI 格式连接替换旧样式 (+) 连接的 Oracle 文档。我很难将其转换为我认为是两个左外连接操作。我的挂断是 select 语句中的两个以及应该放置连接的确切位置。

这是我的查询:

SELECT
  AUP.USERNAME,
  AUP.MENU_STRING MODULE,
  NVL(UGA.PERMISSION,AUP.DEFAULT_PERMISSION) PERMISSION
FROM
  (SELECT
    DU.USERNAME,
    A.PROGRAM_ID,
    A.MENU_STRING,
    'Y' DEFAULT_PERMISSION
  FROM
    APPLICATION A,
    DBA_USERS DU
  WHERE 
    A.PROGRAM_ID NOT IN ('.SEPARATOR')
    AND DU.USERNAME NOT LIKE '%#') AUP,
  (SELECT
    USER_ID,
    PROGRAM_ID,
    PERMISSION
  FROM
    USER_PGM_AUTHORITY
  WHERE
    PROGRAM_COMPONENT='PROGRAM') UGA
WHERE
  AUP.USERNAME=UGA.USER_ID(+)
  AND AUP.PROGRAM_ID=UGA.PROGRAM_ID(+)
  AND aup.menu_string = 'Vendor Maintenance'
ORDER BY
  AUP.USERNAME,
  AUP.MENU_STRING;

【问题讨论】:

    标签: oracle select join


    【解决方案1】:

    借用 10 年前的帖子。我已尝试使解决方案适应我的查询,但我无法弄清楚。

    这是我的查询,我想将 (+) 替换为 LEFT JOIN

    FROM a,b,c
    WHERE b.a  = '101'
    AND a.a    = '202'
    AND b.c    = a.c
    AND a.d    = c.d(+)
    AND ROWNUM = 1;
    

    【讨论】:

      【解决方案2】:

      您可以使用命名的子查询对其进行重构以使其更具可读性:

      WITH AUP AS (                                -- Moved to a named sub-query
        SELECT
          DU.USERNAME,
          A.PROGRAM_ID,
          A.MENU_STRING,
          'Y' DEFAULT_PERMISSION
        FROM
          APPLICATION A
          CROSS JOIN                               -- No apparent join condition so used an explicit CROSS JOIN.
          DBA_USERS DU
        WHERE 
              A.PROGRAM_ID  NOT IN ('.SEPARATOR')
          AND DU.USERNAME   NOT LIKE '%#'
          AND A.MENU_STRING = 'Vendor Maintenance' -- Moved to the appropriate sub-query
      ),
      UGA AS (                                     -- Moved to a named sub-query
        SELECT
          USER_ID,
          PROGRAM_ID,
          PERMISSION
        FROM
          USER_PGM_AUTHORITY
        WHERE
          PROGRAM_COMPONENT='PROGRAM'
      )
      SELECT
        AUP.USERNAME,
        AUP.MENU_STRING MODULE,
        NVL(UGA.PERMISSION,AUP.DEFAULT_PERMISSION) PERMISSION
      FROM
        AUP
        LEFT OUTER JOIN
        UGA
        ON (    AUP.USERNAME  =UGA.USER_ID
            AND AUP.PROGRAM_ID=UGA.PROGRAM_ID )
      ORDER BY
        AUP.USERNAME,
        AUP.MENU_STRING;
      

      【讨论】:

        【解决方案3】:

        连接在AUPUGA之间:

        SELECT
          AUP.USERNAME,
          AUP.MENU_STRING MODULE,
          NVL(UGA.PERMISSION,AUP.DEFAULT_PERMISSION) PERMISSION
        FROM
          (SELECT
            DU.USERNAME,
            A.PROGRAM_ID,
            A.MENU_STRING,
            'Y' DEFAULT_PERMISSION
          FROM
            APPLICATION A,
            DBA_USERS DU
          WHERE 
            A.PROGRAM_ID NOT IN ('.SEPARATOR')
            AND DU.USERNAME NOT LIKE '%#') AUP
        LEFT JOIN
          (SELECT
            USER_ID,
            PROGRAM_ID,
            PERMISSION
          FROM
            USER_PGM_AUTHORITY
          WHERE
            PROGRAM_COMPONENT='PROGRAM') UGA
        ON AUP.USERNAME=UGA.USER_ID
        AND AUP.PROGRAM_ID=UGA.PROGRAM_ID
        WHERE aup.menu_string = 'Vendor Maintenance'
        ORDER BY
          AUP.USERNAME,
          AUP.MENU_STRING;
        

        【讨论】:

          【解决方案4】:

          我认为这样做可以:

          SELECT
            AUP.USERNAME,
            AUP.MENU_STRING MODULE,
            NVL(UGA.PERMISSION,AUP.DEFAULT_PERMISSION) PERMISSION
          FROM
            (SELECT
              DU.USERNAME,
              A.PROGRAM_ID,
              A.MENU_STRING,
              'Y' DEFAULT_PERMISSION
            FROM
              APPLICATION A,
              DBA_USERS DU
            WHERE 
              A.PROGRAM_ID NOT IN ('.SEPARATOR')
              AND DU.USERNAME NOT LIKE '%#') AUP
          LEFT JOIN
            (SELECT
              USER_ID,
              PROGRAM_ID,
              PERMISSION
            FROM
              USER_PGM_AUTHORITY
            WHERE
              PROGRAM_COMPONENT='PROGRAM') UGA
          ON
            AUP.USERNAME=UGA.USER_ID
            AND AUP.PROGRAM_ID=UGA.PROGRAM_ID
          WHERE
            aup.menu_string = 'Vendor Maintenance'
          ORDER BY
            AUP.USERNAME,
            AUP.MENU_STRING;
          

          【讨论】:

          • 为了保持一致性和清晰度,我还将APPLICATION A, DBA_USERS DU 更改为APPLICATION A CROSS JOIN DBA_USERS DU
          • 我相信这是完美的。我试图在第一个 from 之后放置整个 join /on 语句,但我收到错误说 uga 不存在(因为它尚未创建)。我找不到像这样拆分声明的任何地方。谢谢。
          猜你喜欢
          • 1970-01-01
          • 2017-04-08
          • 2014-07-08
          • 2017-03-15
          • 1970-01-01
          • 2015-09-26
          • 2010-11-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多