SQL:请改进我的 select-where-subquery-returns-one 查询

Posted

技术标签:

【中文标题】SQL:请改进我的 select-where-subquery-returns-one 查询【英文标题】:SQL: please improve my select-where-subquery-returns-one query 【发布时间】:2012-03-15 04:26:25 【问题描述】:

对于以下问题,我已经有了一个可行的解决方案,但我担心它是愚蠢的或低效的。

有一个带有(id, attributes...) 列的Thing 表和一个带有(id, thing_id, version_attributes...) 列的ThingVersion 表问题是从Thing 中选择一个对应的ThingVersion 行。

目前我有类似的东西

SELECT Thing.id AS id, Foo.whatever
FROM Thing JOIN Foo ON Thing.id=Foo.thing_id
WHERE Thing.id IN (
    SELECT thing_id FROM ThingVersion TV
    WHERE 1 = (
        SELECT COUNT(*)
        FROM ThingVersion TV2
        WHERE TV2.thing_id = TV.thing_id)
    )
ORDER BY Foo.whatever

它似乎给出了正确的结果,作为一个强调的非专家,它似乎是不言自明的,但是——三个选择了?!?! -- 我不禁觉得一定有更好的办法。

有吗?

【问题讨论】:

【参考方案1】:

您可以在子查询中使用HAVING 子句:

SELECT Thing.id AS id, Foo.whatever
  FROM Thing JOIN Foo ON Thing.id=Foo.thing_id
 WHERE Thing.id IN
        ( SELECT thing_id
            FROM ThingVersion TV
           GROUP BY thing_id
          HAVING COUNT(*) = 1
        )
 ORDER BY Foo.whatever
;

您还可以消除主查询中的JOIN

SELECT thing_id AS id, whatever
  FROM Foo
 WHERE thing_id IN
        ( SELECT thing_id
            FROM ThingVersion TV
           GROUP BY thing_id
          HAVING COUNT(*) = 1
        )
 ORDER BY whatever
;

(我假设出现在Foo.thing_idThingVersion.thing_id 中的每个值都肯定出现在Thing.id。)

【讨论】:

【参考方案2】:
SELECT Thing.id AS id, Foo.whatever
FROM Thing JOIN Foo ON Thing.id=Foo.thing_id
where Thing.idin (select thing_id from ThingVersion group by thing_id having COUNT(*)>1)

【讨论】:

【参考方案3】:

使用严格 JOIN 的解决方案:

SELECT t.*
FROM Thing t
JOIN ThingVersion tv1
  ON tv1.thing_id = t.id
LEFT JOIN ThingVersion tv2
  ON tv2.thing_id = t.id
  AND tv2.id <> tv1.id
WHERE tv2.id IS NULL

使用 GROUP BY 和 COUNT 的解决方案:

SELECT t.* 
FROM Thing t
JOIN ThingVersion tv
  ON tv.thing_id = t.id
GROUP BY t.id
HAVING COUNT(t.id) = 1;

试一试两者的性能。

【讨论】:

+1 连接几乎肯定会胜过GROUP BY ... HAVING 解决方案。

以上是关于SQL:请改进我的 select-where-subquery-returns-one 查询的主要内容,如果未能解决你的问题,请参考以下文章

请帮助改进要编译的数据[关闭]

SQL Server 和实体框架性能改进

如何改进 Linq-To-Sql 代码

sql优化:通过子查询或自己的查询计算所有行/其他改进

SQL 查询非常慢 - 我该如何改进它?

如何改进表数据库设计