Sql 工会条款的替代条款
我在努力自学,更好地理解联盟的替代方法,并发现何时可以使用连接 当我在玩这个游戏的时候,如果没有工会,我似乎无法得到我想要的东西。是否可以在单个查询中写入此内容Sql 工会条款的替代条款,sql,oracle,Sql,Oracle,我在努力自学,更好地理解联盟的替代方法,并发现何时可以使用连接 当我在玩这个游戏的时候,如果没有工会,我似乎无法得到我想要的东西。是否可以在单个查询中写入此内容 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') AN
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
提前感谢您的指导或帮助。请检查此功能是否有效
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))
这是旧的过时的
A,B
join语法真正显示其年龄的情况之一,当您有一些条件必须放在特定的ON
子句中,其他条件必须放在where
子句中。以这种方式编写此查询将非常困难,以后阅读和理解它将更加困难。最好总是写出完整的内部连接
,左连接
,等等。每当你看到一个不同的连接,资源就被浪费了
SELECT a.id
FROM table1 a
where a.ind IS NULL
and ( exists (select null from table2 b
WHERE a.id = b.id
AND b.year >= '2017'
AND b.code IN ('01','02','03')
AND b.flag NOT IN ('F','L') )
or exists (SELECT null FROM table3 c
WHERE a.id = c.id
AND c.area = 'MAIN'
AND SYSDATE >= c.startdt)
)
表2(id、年份、代码、标志)和表3(id、区域、起始时间)上的索引不会影响性能。Oracle 11gR2不允许我有一个名为“开始”的列。我会使用它
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
+表联接在大多数情况下都可以重写。在一些数据库中,它甚至可能选择更好的执行计划(例如:Oracle)您现在拥有的只是一个查询,尽管它使用一个联合。我认为另一种选择是将所有三个表连接在一起,但是WHERE
逻辑可能会变得非常糟糕(如果你不知道这意味着什么,这意味着丑陋之外)。在查询中不需要使用DISTINCT
,因为UNION
将删除任何重复项。您可以提供一个SQL FIDLE来处理一些测试数据。这是一种浪费,您无缘无故地加入表2和表3,导致笛卡尔坐标。我倾向于使用in而不是EXISTS,因为它较短,通常更易于阅读。您必须小心,并且(几乎)始终使用NOT EXISTS(尽管)。@gpeche(几乎)始终使用NOT EXISTS(尽管)?@gpeche您对Oracle来说是新手吗?exists的优点是在找到一行时立即停止,而in将创建满足条件的所有行的视图,并对它们进行排序和区分。当然,有了基于成本的floptimizer,你永远不会确定。@GerardH.Pille-你似乎太老了,不适合Oracle。你所描述的很早以前就改变了;至少从版本10开始,中的和存在
会导致相同的执行计划。@Magnus read。基本上,
中的和存在
是“等效的”,但是不在
和不存在
在出现NULL时表现不同。在大多数情况下,“直观”行为几乎总是由NOT EXISTS
提供的。两个外部联接后跟两个“is NOT null”将它们再次转换为内部联接。为什么不呢?@GerardH.Pille这叫做排除加入。这是一个非常好的常见模式,而且肯定不会将事情再次返回到内部连接。正常模式只需检查是否为空
而不是是否为非空
,但在这种情况下,使用或
执行两次模式,结果仍然正确。排除联接!这证明人活到老学到老。我还是觉得你在浪费时间。
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
)
)