【问题标题】:Oracle - How to write a query with multiple outer joins and joins to dates in ansi sqlOracle - 如何在 ansi sql 中编写具有多个外部连接和日期连接的查询
【发布时间】:2015-02-17 12:16:36
【问题描述】:

我正在尝试使用带有外部连接的 ansi (sql 92) sql 编写以下查询:

select *
from   ota_delegate_bookings     odb,
       ota_events                oe,   -- aka Class
       per_all_assignments_f     paaf
where  oe.event_id = odb.event_id
and    paaf.person_id (+) = odb.delegate_person_id
and    paaf.assignment_type (+) in ('E', 'C')
and    paaf.primary_flag (+) = 'Y' 
and    oe.course_start_date between paaf.effective_start_date (+) and paaf.effective_end_date (+)

我得到了可怕的ORA-01417: a table may be outer joined to at most one other table 错误。我想知道较新的 ansi sql 外连接语法是否没有外连接到多个表的限制;但我不知道如何将其编写为 ansi sql。您如何处理多个连接以及一个连接如何使用 between?

【问题讨论】:

    标签: sql oracle outer-join


    【解决方案1】:

    你有右连接和左连接的组合,这就是导致一个表被外部连接到最多另一个表的错误的原因。表 per_all_assignments_f 外连接到 ota_eventsota_delegate_bookings。我不知道这个限制是否也适用于 ANSI SQL 连接;我的建议是使用子查询或 CTE(我不确定连接是否有意义)。

    (另外,我要问一下,你真的需要SELECT *吗?)

    WITH ota AS (
        SELECT * FROM ota_delegate_bookings odb
         INNER JOIN ota_events oe
            ON odb.event_id = oe.event_id
    )
    SELECT * FROM ota LEFT JOIN per_all_assignments_f paaf
        ON ota.delegate_person_id = paaf.person_id
       AND ota.course_start_date BETWEEN paaf.effective_start_date AND paaf.effective_end_date
       AND paaf.assignment_type IN ('E', 'C')
       AND paaf.primary_flag = 'Y';
    

    这也可以使用子查询来编写:

    SELECT * FROM (
        SELECT * FROM ota_delegate_bookings odb
         INNER JOIN ota_events oe
            ON odb.event_id = oe.event_id
    ) ota LEFT JOIN per_all_assignments_f paaf
        ON ota.delegate_person_id = paaf.person_id
       AND ota.course_start_date BETWEEN paaf.effective_start_date AND paaf.effective_end_date
       AND paaf.assignment_type IN ('E', 'C')
       AND paaf.primary_flag = 'Y';
    

    【讨论】:

    • 啊!避免隐式连接的另一个好理由。使用显式的JOIN 运算符会让你更详细地思考你在做什么;)
    猜你喜欢
    • 2018-09-10
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多