【问题标题】:Unnest an SQL statement取消嵌套 SQL 语句
【发布时间】:2009-07-13 21:55:43
【问题描述】:

我有这个有效的 SQL 语句:

select oriseqs.newID from oriseqs WHERE oriseqs.singlets=1 AND 
oriseqs.newID not in (select newID from cleanreport WHERE trash!="")

我的问题是如何避免在这种特殊情况下在另一个内部进行选择。我的意思是用没有嵌套选择的方式重写select语句。

如果需要,这里是相关架构:

CREATE TABLE cleanreport(newID TEXT, perc TEXT, inicoord INTEGER, endcoord INTEGER, ilen INTEGER, trash TEXT, comments TEXT);
CREATE TABLE oriseqs(newID TEXT, oldID TEXT, rawseq TEXT, singlets BOOLEAN);

【问题讨论】:

  • 您已经遗漏了至少一半的架构:您在两个表上有哪些索引?

标签: sql sqlite


【解决方案1】:
SELECT oriseqs.newID 
FROM oriseqs AS o
LEFT JOIN cleanreport AS cr ON o.newID = cr.newID
WHERE oriseqs.singlets=1 
AND trash != ""
AND cr.newID IS NULL

什么是 PK?

【讨论】:

  • 两个表的主键。我通常喜欢检查主键是否为空
  • 您应该将 'AND垃圾!= ""' 移动到 ON 子句。这将改变(减少)成功连接的行,进而改变由 'AND cr.newID IS NULL' 过滤的行
  • 它在 SQLite 中无法使用您的查询 :( 无论如何,我将保留它(使用嵌套选择),但只是出于好奇而想尝试一下。
【解决方案2】:

有多种方法可以解决几乎所有 SQL 问题。在您的特定问题中,想到的第一个替代方法是使用左外连接并在第二个表的连接列中测试 null。但是,您的查询是完全合理的。我认为没有理由改变它并且怀疑 - 至少在第一次检查时 - 你会从替代品中看到更好的性能。

【讨论】:

  • 保留嵌套查询的好处是,作为 QA 工程师,恕我直言,以后更容易对查询进行逆向工程。
  • 这是另一个好点。左外连接解决方​​案的目的并不那么明显。
【解决方案3】:
select o.newID 
from            oriseqs     o
left outer join cleanreport c on c.newID = o.newID
WHERE o.singlets=1 
AND c.newID is null;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2012-07-15
    • 2012-08-13
    相关资源
    最近更新 更多