SQL查询 - 根据标志获取所有记录

时间:2012-04-25 19:00:35

标签: sql-server-2008

我在MS SQL 2008中有一个表,其中有一个名为Status的列。它可以具有“A”或“I”或“P”作为值。我有一个存储过程,它以@Status为参数。如果参数是null,我需要检索状态为A或I或P的所有记录(基本上忽略Status字段)。如果参数仅为A(例如),我只需要获取具有A作为状态的记录。如何在没有IF.. ELSE的单个SELECT语句中完成此操作?

 -- This is just a snippet of a larger query. 
 -- Can the following be done without IF ELSE?
    IF @Status = NULL
       BEGIN
         SELECT * FROM Person
       END
    ELSE SELECT * FROM Person WHERE Status = @Status

编辑:我的目标不是两次复制相同的逻辑。 select语句有很多连接和东西,我不想在else条件下再次重复它。

编辑#2:我的不好 - 我再次检查了表格,它确实包含NULL状态的记录,这是我不想要的。这是表格 -

Id      Status
--------------
1        A
2        I
3        P
4        NULL

如果@Status为“-1”(我将参数默认为-1),我想要1, 2, 3条记录。我该如何编写查询?

5 个答案:

答案 0 :(得分:1)

您可以使用OR:

来完成
SELECT * FROM Person WHERE Status = @Status OR @Status IS NULL

或UNION ALL:

SELECT * FROM Person WHERE Status = @Status
UNION ALL
SELECT * FROM Person WHERE @Status IS NULL

答案 1 :(得分:1)

第三种选择:

SELECT * FROM dbo.Person WHERE Status = COALESCE(@Status, Status);

或者您可能更喜欢ISNULL:

SELECT * FROM dbo.Person WHERE Status = ISNULL(@Status, Status);

只是为了完整性,虽然这里的选择性极不可能证明它的合理性,但你可能会发现@Status IS NULL和@Status IS NOT NULL的计划变化很大,因为用一个或另一个来缓存一个计划可以导致在相反的情况下表现不佳。解决这个问题的一种方法是动态SQL。同样,由于免责声明在您的情况下这可能是一个不错的选择,它是这些计划钉住COALESCE / ISNULL / OR选项的常用替代方案。

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = N'SELECT * FROM dbo.Person' + 
  COALESCE(N' WHERE Status = ''' + CONVERT(VARCHAR(12), @Status) + '''', '');

PRINT @sql;
--EXEC sp_executesql @sql;

当然你认识你shouldn't be using SELECT * in production code,对吧?

答案 2 :(得分:0)

SELECT * FROM Person WHERE @Status IS NULL OR Status = @Status

答案 3 :(得分:0)

declare @status CHAR(1)
set @status = 'A'
select * from Person where (@status IS null) or (@status = status)

当@status = NULL时,此查询将返回所有记录。

答案 4 :(得分:0)

这应该这样做:

select * from Person
where (@Status is not null and Status = @Status) or
      (@Status is null and Status in ('A', 'I', 'P'))