示例查询:
select *
from A join B on A.ID = B.SOMEVALUE
where A.VALUE="something" and
B.ID =
(select ID from B where SOMEVALUE = A.ID and
THISDATE = (select max(SOMEDATE) from B where ...))
所以,如果你能阅读SQL,你应该看到我正在做几个相关的子查询来缩小连接的结果。 (是的,这非常简化)。
在某些情况下子查询:
select ID from B where SOMEVALUE = A.ID and
THISDATE = (select max(SOMEDATE) from B where ...)
可以返回多于1个值,这会导致错误
“子查询返回的值超过1。 这是不允许的 子查询跟随=,!=,<,< =,>,> = 或者子查询用作 表述“。
我完全期待。这显然不是一件好事,我有代码(希望)防止这些副本首先进入数据库(即表B 应该只有1行匹配
SOMEVALUE = A.ID and max(SOMEDATE)
条件),但最终用户如果没有创造性,却找不到破解软件的方法。
现在问我的问题:
将第一个子查询更改为
会更好吗?select top 1 * from B ...
防止用户在/ if(希望永远不会)出现这种情况或让错误发生时看到错误。我倾向于不添加top语句并让错误通过而不是让用户看到可能不正确的数据。我想知道在这样的情况下是否有人对最佳实践有任何想法......
答案 0 :(得分:11)
通常TOP 1是个好主意。
考虑一个包含数百万行的大型表,而您所匹配的列上没有索引,但是您只需查找一行。
SELECT TOP 1表示只要找到一个项目,表扫描就会停止。
如果没有TOP 1,表格扫描将一直持续到最后。
与涉及扫描(或蛮力)进行搜索的任何事情一样。使用TOP 1,它应该比不使用TOP 1平均快50%。
但是,根据您需要返回的内容,通常可以通过使用EXISTS获得真正的性能提升。
而不是写
SELECT * FROM table t
WHERE t.id = (SELECT TOP 1 foreignid from table2)
您可以使用
SELECT * FROM table t
WHERE EXISTS (SELECT 1 from table2 WHERE foreignid = t.id)
答案 1 :(得分:4)
为什么要加入表A和B ...然后在子查询中从B中选择...并与A ???中的列进行比较
这不等同于:
select *
from A join B on A.ID = B.SOMEVALUE
where A.VALUE="something" and
THISDATE = (select max(SOMEDATE) from B where ...))
此外,如果您希望从整个查询中获得一行总数......这不会起作用:
select top 1 *
from A join B on A.ID = B.SOMEVALUE
where A.VALUE="something"
Order by B.SOMEDATE DESC
答案 2 :(得分:4)
编码练习:将top1放在子查询中,该子查询需要返回单个值。
优点:
缺点:
答案 3 :(得分:1)
我推荐使用TOP 1方法。它可能有助于提高性能(不太可能伤害它)。
没有它你会发现错误的想法是光荣的,但有点错位。如果从现在起几个月内发生错误,那么它根本不会直观或者发生了什么。相反,我专注于在其他地方强制执行数据完整性。
答案 4 :(得分:0)
为什么不在子选择的末尾使用LIMIT 1
?
答案 5 :(得分:0)
如果您只想返回一行,则可以执行以下两项操作之一。第一种是改变你的平等检查,而不是像这样检查包含
select ID from B where SOMEVALUE = A.ID and
THISDATE IN (select max(SOMEDATE) from B where ...)
(注意IN)
其次你可以做到
select TOP 1 ID from B where SOMEVALUE = A.ID and
THISDATE IN (select max(SOMEDATE) from B where ...)
如果你只是只找一个值。
或者如您所说,您可以将子查询更改为SELECT TOP 1,在我看来,这是正常的,因为只要WHERE子句不依赖于外部查询,它就可能执行嵌套查询只有一次并依赖于那里的静态存储值,如此
select ID from B where SOMEVALUE = A.ID and
THISDATE = (select TOP 1 * from B where ...)
所以有一些选择,但我不完全确定它们的效率。