CASE声明

时间:2017-12-04 20:06:13

标签: sql-server tsql

我见过很多关于将CASE语句放在WHERE子句中的帖子。但是,在我的情况下,我想在CASE语句中放入一个WHERE语句,我认为不能这样做。

我的情况是,我有一个正在进行许多数据库的视图。在其中一半中,我需要一个WHERE子句。在另一半,我不需要WHERE子句。保留它并不是有害的,因为我不会得到错误的数据,但是它会大大减慢查询速度,因为它必须在不必要时读取和排序大表。

Status_Table
ID    Status
1     Active
2     Inactive
3     Unknown    --this row of data will not exist in some DBs

Item_table
Item_ID    Status    value1    value2
1001          3      .....     .....
1002          1      .....     .....

我想做的就是这样。

-- big nasty ugly query with various CTEs, selects, and joins
CASE    WHEN (SELECT MAX(ID) FROM Status_table) = 3
        THEN WHERE Item_Table.Status != 3
        ELSE WHERE 1=1
END

最终,我可以通过使用动态SQL构建查询来解决这个问题,但我希望有一个更优雅的解决方案。

4 个答案:

答案 0 :(得分:2)

您正在尝试构建条件WHERE子句,是吗?我认为这样的事情对你想做的事情非常有效:

WHERE (EXISTS (SELECT 1 FROM Status_table WHERE ID = 3) 
        AND Item_Table.Status != 3)
        OR
        NOT EXISTS (SELECT 1 FROM Status_table WHERE ID = 3) 

答案 1 :(得分:0)

SQL Fiddle

MS SQL Server 2014架构设置

CREATE TABLE Status_Table ( ID int, [Status] varchar(30) ) ;
INSERT INTO Status_Table ( ID, [Status] )
VALUES 
  ( 1,'Active' ), (2,'Inactive'), (3,'Unknown')
;

CREATE TABLE Item_table ( Item_ID int, [Status] int, value1 varchar(10), value2 varchar(10) ) ;
/* NOTE: Item_table.[Status] should be a descriptive name, like [StatusID], or something not the same name as a different datatype column in the relation table. */
INSERT INTO Item_Table ( Item_ID, [Status], value1, value2 )
VALUES (1001,3,'Bill','Exclude')
  ,(1002,1,'Ted','Include')
  ,(1003,3,'Rufus','Exclude')
  ,(1004,2,'Jay','Include')
  ,(1005,5,'Bob','BadRecord')
;

查询1

SELECT s1.Item_ID, s1.Status, s1.Value1, s1.Value2
FROM (
  SELECT i.Item_ID, i.Status, i.Value1, i.Value2
    , RANK() OVER (ORDER BY s.ID DESC) AS rn
  FROM Item_Table i
  RIGHT OUTER JOIN Status_Table s ON i.[Status] = s.ID
) s1
WHERE s1.rn <> 1

<强> Results

| Item_ID | Status | Value1 |  Value2 |
|---------|--------|--------|---------|
|    1004 |      2 |    Jay | Include |
|    1002 |      1 |    Ted | Include |

答案 2 :(得分:0)

如果它的性能在你开始使用DECLARE和SET之后。 它只需要执行ONCE !!!

DECLARE @UnkownExists AS INT
    SET @UnkownExists = (select count(*) from Status_table where ID = 3)

-- big nasty ugly query with various CTEs, selects, and joins
  WHERE (@UnkownExists=1 AND Item_Table.Status != 3) OR @NoUnknown=0 

答案 3 :(得分:0)

你可以试试这个:

CASE WHEN (SELECT MAX(ID) FROM Status_table) = 3 
    THEN 3 
    ELSE (SELECT MAX(ID)+1 FROM Status_table) --Invalid value that will not exist
END <> Item_Table.Status