2017-12-04 2 views
0

WHERE 절 안에 CASE 문을 넣는 것에 관한 많은 게시물을 보았습니다. 그러나, 제 경우에는 CASE 문 안에 WHERE 문을 넣기를 원합니다. 나는 할 수 있다고 생각하지 않습니다.WHERE where CASE statement

제 상황은 많은 데이터베이스에서 진행되는 뷰가 있습니다. 그 중 절반은 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을 사용하여 쿼리를 구성하여이 문제를 해결할 수 있지만 좀 더 세련된 솔루션을 기대하고 있습니다.

+0

귀하의 경우 문이 이해가 나던. MAXID = 3 일 때 어떤 값을 설정 하시겠습니까? 그리고! = 3을 사용하여 동일한 표현식을 작성하고 값을 설정하십시오. – plaidDK

+0

CASE는 스칼라 값을 반환하는 데 사용되는 표현식입니다. WHERE 절은 select 문 결과를 필터링하는 데 사용됩니다. 단순히 당신이하려고하는 것은 당신이 그것을하려는 방식대로 할 수 없다. 동적 SQL은 필요하지만, 뷰에서는 그렇게 할 수 없습니다. 아마도 여기서 일어나고있는 일을 재평가해야 할 것입니다. –

+0

'Status_Table'에서'max (ID)'를 제외하려고하거나이 값을 이미'Item_Table'에 알려줄 것입니까? 그렇다면,'Item_Table' 값에 기초하여 정상적인'WHERE'를 필터링하십시오. 또한'ROW_NUMBER()'윈도우 함수를 사용하여'MAX (ID)'를 얻을 수 있습니다. – Shawn

답변

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) 
+0

그게 다야! 나는 그것을 처리하는 논리적 인 방법이 있어야한다는 것을 알았지 만 나는 안개 속에서 길을 잃었습니다. 첫 번째 EXISTS 절이 실패하면 u 리 옵티마이 저가 테이블 스캔 (또는 인덱스 스 5)을 h 제해야합니다. –

0

SQL Fiddle

MS SQL 서버 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 | 
0

성능이 후 선언하고 SET 사용하기 시작합니다. 한 번만 실행하면됩니다!

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 
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