当您期望单个结果时,“SELECT TOP 1”真的是获得单个结果的最佳方式吗?

时间:2016-11-08 17:35:44

标签: sql sql-server tsql

每当我期望我需要在变量中存储单个结果时,我会执行类似

的操作
DECLARE @id INT = SELECT TOP 1 [Id] FROM [Stuff] WHERE [Stuff].[Name] = 'Harry';

因为SQL Server抱怨我是否

DECLARE @id INT = SELECT [Id] FROM [Stuff] WHERE [Stuff].[Name] = 'Harry';

即使保证最多只有1个结果 (例如,因为[Name]UNIQUE约束)

我想知道是否有更合适的方法。例如,在C#LINQ中有SingleSingleOrDefault,如

var id = context.Stuff.Single()?.Name; 

更具表现力。

4 个答案:

答案 0 :(得分:2)

您的语法无效。如果最多只有一行,这应该有效:

DECLARE @id INT = (SELECT [Id] FROM [Stuff] WHERE [Stuff].[Name] = 'Harry');

如果您只是想要额外的话,可以添加TOP 1,确保不会出现运行时错误。

请记住:子查询总是需要自己的括号。

答案 1 :(得分:0)

下面的内容如果 - 在多行的情况下,它将为您提供查询碰巧遇到的最终值

DECLARE @id INT;
SELECT  @id = [Id] FROM [Stuff] WHERE [Stuff].[Name] = 'Harry';

我不知道你的想法是否更好,更糟或没有差别 - 如果有很多“哈利”的话,情况可能会更糟。

答案 2 :(得分:0)

与戈登所说的括号相同。现在考虑以下SQL并记下我的评论:

-- create table with one 'harry'
DECLARE @stuff TABLE (id int identity, name varchar(100));
INSERT @stuff VALUES ('harry');

-- this will succeed, SQL will NOT complain
DECLARE @id int = (SELECT id FROM @stuff WHERE name = 'harry')

-- add another 'harry'
INSERT @stuff VALUES ('harry');

-- this will fail because the subquery returns 2 rows
DECLARE @ids int = (SELECT id FROM @stuff WHERE name = 'harry');

请记住,如果没有附带的ORDER BY子句,TOP语句的结果不能保证始终相同。

答案 3 :(得分:0)

如果您确定您的查询只返回一条记录,则可以使用:

  

DECLARE @id INT

     

SELECT @id = [Id] FROM [Stuff] WHERE [Stuff]。[Name] ='Harry';