2013-09-05 2 views
0

내 WHERE 절 매개 변수가 비어 있거나 null 인 경우 모든 행을 반환하는 CASE를 사용하고 있습니다. 이것은 단일 valuses와 잘 작동합니다. 그러나 IN 절을 사용할 때는 그리 좋지 않습니다. 예 :T-SQL에서 IN 절이있는 CASE 사용

매우 잘 작동합니다. 일치하지 않으면 모든 레코드가 반환됩니다.

AND 
Name = CASE WHEN @Name_ != '' THEN @Name_ ELSE Name END 
AND 

이 또한 작동하지만 CASE 표현식을 사용하는 방법은 없습니다, 그래서 어떤 가치를 제공하지 않으면 내가 어떤 기록을 볼 수 없습니다 :

AND 
Name IN (Select Names FROM Person Where Names like @Name_) 
AND 

이 나는 ​​케이스를 사용할 수를 두 번째 예? 일치하지 않으면 모든 이름이 반환됩니까?

답변

1

어쩌면 coalesce 당신은 또한 isnull 기능을 사용할 수 있습니다, Mattfew 호수 말했듯이

AND 
Name IN (Select Names FROM Person Where Names like coalesce(@Name,Name)) 
AND 

문제 해결에 사용됩니다

Name IN (Select Names FROM Person Where Names like isnull(@Name,Name)) 
+0

이것은 좋은 제안입니다. 왜 누구가 그 투표를하지 않을지 알지 못합니다. – SerenityNow

+0

@RedSoxFred 저는 모르겠습니다. 아마도'like' 대신에'hay =''hade하지만 저는 그것을 바꿨습니다. 감사! – Parado

+0

@ RedSoxFred 당신은 의식입니다. Parado는 저에게 우수한 결과를주었습니다. T-SQL 지식을 어디서 배울 수 있습니까? 너를 눌러라. –

1

아마도 다음과 같이 할 수 있습니까?

AND 
Name IN (Select Names FROM Person Where Names LIKE 
     CASE WHEN @Name_ = '' OR @Name_ IS NULL THEN '%' ELSE @Name_ END) 
AND 

이 패턴 '%'를 (모든 일치하는) null 또는 빈 @Name_ 매개 변수를 제공 한 경우에만 사용합니다, 그렇지 않으면 그것은 @Name_에 의해 지정된 패턴을 사용합니다. ,

AND 
Name IN (Select Names FROM Person Where Names LIKE 
     ISNULL(NULLIF(@Name_, ''), '%')) 
AND 
1

case 문 필요 없음 그냥 중첩 된 OR 조건을 사용

또는이 같은 작업을해야합니다.

AND ( Name IN (Select Names FROM Person Where Names like @Name_) 
    OR 
     @Name_ IS NULL 
    ) 
AND 
1

이것은

DECLARE @Name NVARCHAR(100) 

SET @Name = '' 

DECLARE @Person TABLE (NAME NVARCHAR(100)) 

INSERT INTO @Person VALUES ('fred') 
INSERT INTO @Person VALUES ('jo') 

DECLARE @Temp TABLE 
    (
     id INT , 
     NAME NVARCHAR(100) 
    ) 

INSERT INTO @Temp (id, NAME) VALUES (1, N'') 
INSERT INTO @Temp (id, NAME) VALUES (5, N'jo') 
INSERT INTO @Temp (id, NAME) VALUES (2, N'fred') 
INSERT INTO @Temp (id, NAME) VALUES (3, N'bob') 
INSERT INTO @Temp (id, NAME) VALUES (4, N'') 

SELECT * FROM @Temp 
WHERE name IN (SELECT name 
        FROM  @Person 
        WHERE  name = CASE WHEN @name != '' THEN @Name 
             ELSE name 
            END) 
+2

나는 다음 사람만큼 투표를 높이 평가하지만, 나는 이유없이 투표에 특히 감사한다. 더 유익하고 비판적입니다. – SerenityNow

+0

오, 나는 그것이 작동하는 것을 안다. 감사한다. – SerenityNow

1
,321 작동 0 거의 확실하게 두 개의 선택과 함께 IF 문을 사용해야합니다. 예 :

IF @Name IS NULL 
    BEGIN 
     SELECT * 
     FROM Person 
    END 
ELSE 
    BEGIN 
     SELECT * 
     FROM Person 
     --WHERE Name LIKE '%' + @Name + '%' 
     WHERE Name = @Name 
    END 

N.B. LIKEwithout wildcards it is no different to equals, 이후로 같음으로 변경 했으므로 성능면에서 차이가 없어야하지만 쿼리를 읽을 다음 사람의 모호성을 막을 수 있습니다. 정확하지 않으려면 과 일치해야하며 주석이있는 WHERE을 사용하고 필요에 따라 와일드 카드를 제거하십시오.

IF의 이유는 두 개의 쿼리가 매우 다른 실행 계획을 가질 수 있지만이를 하나의 쿼리로 결합하여 옵티 마이저가 하나의 계획 또는 다른 계획을 선택하도록하고 있기 때문입니다.

EXECUTE GetPeopleByName1 'asymmetric_keys'; 
EXECUTE GetPeopleByName1 NULL; 

EXECUTE GetPeopleByName2 'asymmetric_keys'; 
EXECUTE GetPeopleByName2 NULL; 

결과는 모두 절차에 대해 동일하지만, 나는이 같은 계획을 각 시간을 얻을 : 나는 두 절차 가치와없이 모두를 실행하면 이제

CREATE TABLE Person 
(  PersonID  INT IDENTITY(1, 1) NOT NULL, 
     Name   VARCHAR(255) NOT NULL, 
     DateOfBirth  DATE NULL 
    CONSTRAINT PK_Person_PersonID PRIMARY KEY (PersonID) 
); 
GO 
CREATE NONCLUSTERED INDEX IX_Person_Name ON Person (Name) INCLUDE (DateOfBirth); 
GO 
INSERT Person (Name) 
SELECT DISTINCT LEFT(Name, 50) 
FROM sys.all_objects; 
GO 

CREATE PROCEDURE GetPeopleByName1 @Name VARCHAR(50) 
AS 
    SELECT PersonID, Name, DateOfBirth 
    FROM Person 
    WHERE Name IN (SELECT Name FROM Person WHERE Name LIKE ISNULL(@Name, Name)); 
GO 

CREATE PROCEDURE GetPeopleByName2 @Name VARCHAR(50) 
AS 
    IF @Name IS NULL 
     SELECT PersonID, Name, DateOfBirth 
     FROM Person 
    ELSE 
     SELECT PersonID, Name, DateOfBirth 
     FROM Person 
     WHERE Name = @Name; 
GO 

:이 스키마를 상상 첫 번째 절차에는 두 번째 계획이 있지만 두 번째 계획은 훨씬 효율적입니다.

enter image description here

사용할 수없는 경우 IF (예를 들어, 당신은 인라인 테이블 값 함수를 사용하는 경우) 다음 UNION ALL를 사용하여 유사한 결과를 얻을 수 있습니다 :

SELECT PersonID, Name, DateOfBirth 
FROM Person 
WHERE @Name IS NULL 
UNION ALL 
SELECT PersonID, Name, DateOfBirth 
FROM Person 
WHERE Name = @Name; 

이되지 않습니다 IF를 사용하는 것만 큼 효율적이지만 첫 번째 쿼리보다 훨씬 효율적입니다. 결론은 덜 항상 더 많지 않다는 것입니다. 예를 들어 IF을 사용하면 좀 더 자세한 정보가 표시되고 더 많은 작업을 수행하는 것처럼 보일 수도 있지만 실제로는 작업량이 적어 훨씬 효율적입니다.

+0

투표해라. 그렇게 열심히 일해라. .. – SerenityNow