복붙노트

[SQL] SQL Server의 조건부 WHERE 절

SQL

SQL Server의 조건부 WHERE 절

나는 어디에서 조건부 절을 필요로하는 SQL 쿼리를 만드는 오전.

그 결과는 아래와 같습니다 :

SELECT 
    DateAppr,
    TimeAppr,
    TAT,
    LaserLTR,
    Permit,
    LtrPrinter,
    JobName,
    JobNumber,
    JobDesc,
    ActQty,
    (ActQty-LtrPrinted) AS L,
    (ActQty-QtyInserted) AS M,
    ((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
FROM 
    [test].[dbo].[MM]
WHERE 
    DateDropped = 0
            --This is where i need the conditional clause 
    AND CASE
            WHEN @JobsOnHold = 1 THEN DateAppr >=  0
            ELSE  DateAppr != 0
        END

위의 쿼리가 작동하지 않습니다. 이것은 올바른 구문되지 않았거나 내가 모르는이 작업을 수행하는 또 다른 방법은 무엇입니까?

그래서 다른 방법이 동적 SQL을 사용하려면 아니면 내가 만약 다른 사람을 사용하여 어디 조항 다른과 같은 쿼리를 사용하여 같은 해결 방법을 사용할 필요하지 않습니다?

해결법

  1. ==============================

    1.이 시도

    이 시도

    SELECT 
        DateAppr,
        TimeAppr,
        TAT,
        LaserLTR,
        Permit,
        LtrPrinter,
        JobName,
        JobNumber,
        JobDesc,
        ActQty,
        (ActQty-LtrPrinted) AS L,
        (ActQty-QtyInserted) AS M,
        ((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
    FROM 
        [test].[dbo].[MM]
    WHERE 
        DateDropped = 0
        AND (
        (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
        OR 
        (ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
        )
    

    당신은 그 다음에 조건에 대한 자세한 내용을보실 수 있습니다.

  2. ==============================

    2.이걸로 해봐 -

    이걸로 해봐 -

    WHERE DateDropped = 0
        AND (
            (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
            OR 
            (ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
        )
    
  3. ==============================

    3.WHERE 절에 CASE 식을 사용하는 방법의 근본적인 질문에 대답하려면 :

    WHERE 절에 CASE 식을 사용하는 방법의 근본적인 질문에 대답하려면 :

    첫 번째 CASE 표현식의 값이 일반 데이터 형식 값이 아닌 부울 값을 가져야한다는 것을 기억하십시오. 그것은 varchar 또는 int로, 또는 무언가이어야한다. 그것은 당신이 [...]에서 선택 이름, 76 = 나이를 말하고 '프랭크'결과 세트, FALSE를 얻을 것으로 예상 할 수없는 같은 이유입니다.

    또한, WHERE 절을 필요로하는 모든 표현은 부울 값을 가질 수 있습니다. 그들은 VARCHAR 또는 int 형의 값을 가질 수 없습니다. 당신은 WHERE 이름 말할 수 없다; 또는 WHERE '프랭크';. 당신은 너무 WHERE 이름 = '프랭크', 그것을 부울 식을 만들기 위해 비교 연산자를 사용해야합니다;

    케이스 식 부울 식의 일측에 있어야한다는 것을 의미한다. 당신은 무언가에 CASE 식을 비교해야합니다. 그것은 그 자체로 서있을 수 없다!

    여기:

    WHERE 
        DateDropped = 0
        AND CASE
                WHEN @JobsOnHold  = 1 AND DateAppr >= 0 THEN 'True'
                WHEN DateAppr != 0 THEN 'True'
                ELSE 'False'
            END = 'True'
    

    결국 왼쪽에있는 CASE 표현식으로 부울 식을 설정하는 방법을 공지 사항 중 '진정한'= '참'또는 = '거짓' '진정한'.

    참고 아무것도 특별한이 '거짓'과 '사실'에 대해이 있다고. 당신은 차라리 경우도 0과 1을 사용할 수 있습니다.

    당신은 일반적으로 우리가 더 잘 알고 부울 식에 CASE 식을 다시 작성할 수 있습니다, 그것은 성능을 위해 일반적으로 좋습니다. 하지만 경우에 따라서는 논리를 변환하는 것보다 기존의 표현을 사용하는 것이 더 쉽습니다 이상의 유지 보수입니다.

  4. ==============================

    4.쿼리의 문제는 CASE 표현식에서 THEN과 ELSE 부분이 표현을해야한다는 것입니다 그 숫자 나 VARCHAR 또는 다른 데이터 유형이 아닌 부울 값으로 평가한다.

    쿼리의 문제는 CASE 표현식에서 THEN과 ELSE 부분이 표현을해야한다는 것입니다 그 숫자 나 VARCHAR 또는 다른 데이터 유형이 아닌 부울 값으로 평가한다.

    당신은 부울 로직 (또는 오히려 삼항 논리가 SQL의 사용)를 사용하고 다시 작성해야합니다

    WHERE 
        DateDropped = 0
    AND ( @JobsOnHold = 1 AND DateAppr >= 0 
       OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
        )
    
  5. ==============================

    5.조건부 WHERE 절을 사용할 때 종종 당신은 인덱스를 사용하는 대규모 데이터 세트에 대한 눈에 잘 띄지 않는 훨씬 비효율적 인 쿼리와 UPP 끝. 당신의 매개 변수의 서로 다른 값에 대한 쿼리를 최적화하는 가장 좋은 방법은 매개 변수의 각 값에 대해 서로 다른 실행 계획을 만드는 것입니다. 이 사용 OPTION (RECOMPILE)을 달성 할 수있다.

    조건부 WHERE 절을 사용할 때 종종 당신은 인덱스를 사용하는 대규모 데이터 세트에 대한 눈에 잘 띄지 않는 훨씬 비효율적 인 쿼리와 UPP 끝. 당신의 매개 변수의 서로 다른 값에 대한 쿼리를 최적화하는 가장 좋은 방법은 매개 변수의 각 값에 대해 서로 다른 실행 계획을 만드는 것입니다. 이 사용 OPTION (RECOMPILE)을 달성 할 수있다.

    이 예에서는 아마 많은 차이를 만들지 만, 조건이 두 사례 중 하나에 사용되어야 언급하지 않았다, 당신은 큰 영향을 알 수있다.

    이 예에서 :

    WHERE 
        DateDropped = 0
        AND (
        (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
        OR 
        (ISNULL(@JobsOnHold, 0) <> 1 AND DateAppr <> 0)
        )
    OPTION (RECOMPILE)
    

    소스 매개 변수 스니핑, 임베딩하고 RECOMPILE 옵션

  6. from https://stackoverflow.com/questions/18629132/conditional-where-clause-in-sql-server by cc-by-sa and MIT license