【问题标题】:Better structured oracle sql query结构更好的 oracle sql 查询
【发布时间】:2017-05-10 05:18:00
【问题描述】:

在 Oracle 11 数据库中,我有 2 个表(CAR 和 CAR_BRAND):

CAR 有以下内容

car_id  |brand
1       |Audi
2       |BMW
3       |VW

CAR_BRAND 有以下内容

brand
Audi
Bmw

使用 INNER JOIN 连接两个表很简单

select c.* from car c
inner join car_brand cb on cb.brand = c.brand;

我有一个要求,当 CAR_BRAND 表为空时,选择 CAR 内的所有记录,否则 select * from CAR 与 CAR_BRAND 表连接。

这可以通过以下方式完成:

SELECT c.* FROM car c JOIN car_brand cb ON cb.brand = c.brand
UNION ALL
SELECT c.*
FROM car c
WHERE NOT EXISTS
(SELECT c.* FROM car c JOIN car_brand cb ON cb.brand = c.brand
);

这很好,但是,有没有更好、更有效的 SQL 来获得最终结果,而不是使用 UNION ALL?

【问题讨论】:

    标签: sql oracle11g


    【解决方案1】:

    您可以在检索汽车时使用变量来计算 car_brand 记录,然后使用 or 测试这两种情况:

    select     car_id, brand
    from       (
                    select     c.*, 
                               cb.brand as match_brand, 
                               @r := @r + if(cb.brand is null,0,1)
                    from       car c
                    cross join (select @r := 0) init
                    left join  car_brand cb
                            on cb.brand = c.brand
               ) base
    where      @r = 0 or match_brand is not null
    

    【讨论】:

    • 也许我错了,但我认为如果第二个表中有记录,OP 想要一个内部连接。没有投反对票。
    • 我怀疑这不是OP想要的,要求只有当CAR_BRAND表中有数据时才加入,否则不要加入。您的查询将始终返回CAR表中的所有记录, 与 CAR_BRAND 表无关,案例:当 Car 表有 x 行,CAR_BRAND 表有 2 条记录时。您的查询将返回 3 行,而 OP 需要 2 行。谢谢
    • 感谢您的回复。 @Mihai 是正确的,如果第二个表中有记录,则需要内部连接。 UNION ALL 完成了这项工作,因此决定采用这种方法。希望有一个速记 SQL 作为替代方案,但可能没有。谢谢
    • @AlanaThoms,你尝试过我提出的left join SQL 吗?我声称它产生的记录与使用 union all 查询得到的记录相同,但效率更高。
    • @trincot,感谢您的回复。 left join 在 CAR_BRAND 表未填充时成功,但是,当在 CAR_BRAND 表中插入一行时,查询仍将返回所有值。
    猜你喜欢
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2018-08-15
    • 2015-09-11
    • 1970-01-01
    • 2020-04-17
    • 2015-10-15
    • 1970-01-01
    相关资源
    最近更新 更多