替代UNION子句

时间:2018-03-28 13:27:42

标签: sql oracle

我正在尝试自学并更好地了解UNION的替代方法,并发现何时可以使用连接。

当我正在玩这个时,如果没有UNION,我似乎无法得到我想要的东西。是否可以在一个查询中写这个?

SELECT DISTINCT a.id
  FROM table1 a, table2 b
 WHERE a.id = b.id
       AND a.ind IS NULL
       AND b.year >= '2017'
       AND b.code IN ('01','02','03')
       AND b.flag NOT IN ('F','L')
UNION
SELECT DISTINCT a.id
  FROM table1 a, table3 c
 WHERE a.id = c.id
       AND a.ind IS NULL
       AND c.area = 'MAIN'
       AND SYSDATE >= c.start

提前感谢您的任何指导或帮助。

4 个答案:

答案 0 :(得分:5)

每当你看到不同的资源时,就会浪费资源。

{{1}}

table2上的索引(id,year,code,flag)和table3(id,area,startdt)不会影响性能。 Oracle 11gR2不允许我有一个名为“start”的列。

答案 1 :(得分:4)

SELECT DISTINCT a.id
FROM table1 a
LEFT JOIN table2 b on b.id = a.id AND b.year >= '2017'
     AND b.code IN ('01', '02', '03') AND b.flag NOT IN ('F', 'L') 
LEFT JOIN table3 c ON a.id = c.id and c.area = 'MAIN' and SYSDATE >= c.start
WHERE a.ind IS NULL
    AND ( b.id IS NOT NULL or c.id IS NOT NULL)

这是旧的过时A,B连接语法真正显示它的年龄,当你有一些条件必须在特定的ON条款中而其他条件必须在{ {1}}条款。以这种方式编写此查询非常困难,以后甚至更难阅读和理解。最好始终写出完整的WHEREINNER JOIN等。

答案 2 :(得分:1)

我会用这个

select a.id
from table1 a
where
  a.ind is null and (
  a.id in (
    select b.id
    from table2 b
    where
    b.year >= '2017'
    and b.code IN ('01','02','03')
    and b.flag NOT IN ('F','L')  
  ) or
  a.id in (
    select c.id
    from table3 c
    where
    c.area = 'MAIN'
    and sysdate >= c.start
  )
)

DISTINCT +表连接大多数时候都可以重写为IN / EXISTS。在几个数据库中,它甚至可以选择更好的执行计划(例如:Oracle)

答案 3 :(得分:-1)

请检查一下是否有效

SELECT DISTINCT a.id
  FROM table1 a, table2 b, table3 c
 WHERE (a.id = b.id
        OR a.id = c.id)
       AND a.ind IS NULL
       AND (( b.year >= '2017'
       AND b.code IN ('01','02','03')
       AND b.flag NOT IN ('F','L'))
       OR (c.area = 'MAIN'
       AND SYSDATE >= c.start))