Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 工会条款的替代条款_Sql_Oracle - Fatal编程技术网

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
  )
)