【问题标题】:How to properly use EXISTS and IN in SQL如何在 SQL 中正确使用 EXISTS 和 IN
【发布时间】:2020-03-03 13:21:53
【问题描述】:

我正在使用 EXISTS 和 IN 比较两个查询。他们都给出了不同的结果。当我使用 IN 查询时,结果是正确的,但是当我使用 EXISTS 查询时,我得到了多条记录,应该只有 1 条记录。

基准:
IN Query - 17 秒得到结果
EXISTS Query - 9-11 秒得到结果

预期结果:
1 - 记录

IN 查询(​​1 条记录):

SELECT CINO, CLIENTID, COID, ADDRVER, ASSETFIX, AVEMONSALE, BRCHAFFL, BUS
  DESC, BUSTYPE, CAPITAL, CONTACT, FACCOND, FIXASSET, FIXTURE, INFADDR,
  INFORMANT, INVENTORY, LANDLORD, LASTYRSALE, LIABILITY, LINEPRDSRV,
  LOTAREA, MACHINE, MAJBAN, MAKE, MOTOR, NATINC, NUMEMPLOY, OBSERVE,
  OBSERVE2, OBTINFORM, OFFCAREA, OFFCBLDG, OFFCLOC, OFFCVALUE, OFFORG,
  OTHERINC, POSITION, RECEIVABLE, REGWITH, REMARKS, REMNEG, REMPOS, RENTEXP,
  YRSOPER, YRINCOME, DATEORG, SUPPLIER 
FROM LCBINV 
WHERE CINO IN (
  SELECT CINO FROM LCMINV WHERE AUDITKY IN (
    SELECT AUDITKY 
    FROM LSAUDIT
    WHERE ENTRYDT > '03-Nov-2019' AND ENTRYTM > '07:15:10'
  )
)

现有查询(200 条记录):

SELECT CINO, CLIENTID, COID, ADDRVER, ASSETFIX, AVEMONSALE, BRCHAFFL, BUS
  DESC, BUSTYPE, CAPITAL, CONTACT, FACCOND, FIXASSET, FIXTURE, INFADDR,
  INFORMANT, INVENTORY, LANDLORD, LASTYRSALE, LIABILITY, LINEPRDSRV,
  LOTAREA, MACHINE, MAJBAN, MAKE, MOTOR, NATINC, NUMEMPLOY, OBSERVE,
  OBSERVE2, OBTINFORM, OFFCAREA, OFFCBLDG, OFFCLOC, OFFCVALUE, OFFORG,
  OTHERINC, POSITION, RECEIVABLE, REGWITH, REMARKS, REMNEG, REMPOS, 
  RENTEXP, YRSOPER, YRINCOME, DATEORG, SUPPLIER 
FROM LCBINV 
WHERE CINO IN (
  SELECT CINO FROM LCMINV WHERE EXISTS (
    SELECT AUDITKY FROM LSAUDIT 
    WHERE ENTRYDT > '03-Nov-2019' AND ENTRYTM > '07:15:10'
  )
)

所以这是我的查询功能,如果ENTRYDT和ENTRYTM大于上次检查的日期和时间,它基本上检查个人信息中是否有更新。

我的问题是为什么我在 EXISTS 查询中获得多条记录,即使 ENTRYDT 不大于日期?

【问题讨论】:

  • 很可能第二个查询使用了错误的列。请为表 LCMINVLSAUDIT 添加别名,并在每列前面加上正确的别名。
  • @TheImpaler 为什么在使用 EXIST 时需要别名?你能发布一个样本吗?
  • 不需要,除非您有相关的子查询。是不是这里的情况?从例子中看不清楚。
  • @TheImpaler 是的,我需要关联子查询,因为表 LCBINV 依赖于 LCMINV 表来检查是否有更新
  • 请为过滤器中的所有列添加别名(WHERE 子句)。

标签: sql oracle


【解决方案1】:

这些查询根本不相似。如果这是in 查询:

WHERE LCBINV.CINO IN (SELECT L2.CINO
                      FROM LCMINV L2
                      WHERE L2AUDITKY IN (SELECT A.AUDITKY 
                                          FROM LSAUDIT A
                                          WHERE A.ENTRYDT > DATE '2019-11-03'AND A.ENTRYTM > '07:15:10'
                                         )
                     )

子查询中带有EXISTS 的等效查询是:

WHERE LCBINV.CINO IN (SELECT L2.CINO
                      FROM LCMINV L2
                      WHERE EXISTS (SELECT 1
                                    FROM LSAUDIT A
                                    WHERE A.AUDITKY = L2.AUDITKY AND
                                          A.ENTRYDT > DATE '2019-11-03' AND
                                          A.ENTRYTM > '07:15:10'
                                   )
                     )

换句话说,您缺少相关性子句。

【讨论】:

  • 是的,看起来像。
  • @TheImpaler 我用了答案它需要很长时间才能得到结果
  • @MarkStewart 如果您比较我使用 IN 查询时的结果时间并且发布的答案非常不同,但它是正确的,但性能成本
  • @Blank317 。 . .这回答了为什么您的两个查询返回不同的结果集的问题。如果您对性能有疑问,请提出 new 问题并提供有关表、现有索引、查询返回的行数的一些信息。 . .
猜你喜欢
  • 2013-05-08
  • 2010-09-06
  • 2015-04-26
  • 2011-12-31
  • 2013-07-07
  • 2014-06-06
  • 2019-06-03
  • 2012-01-19
  • 1970-01-01
相关资源
最近更新 更多