ProgramingTip

둘 다 null 일 수있는 값을 비교하는 방법은 T-SQL입니다.

bestdevel 2020. 11. 9. 20:06
반응형

둘 다 null 일 수있는 값을 비교하는 방법은 T-SQL입니다.


(예 : 기본 키만 다름). "모든 값"을 의미하기 위해 null을 결정하기 때문에 모든 필드는 NULLS를 허용합니다. null로 인해 저장 프로 시저의 다음 문이 작동하지 않습니다.

IF EXISTS(SELECT * FROM MY_TABLE WHERE 
    MY_FIELD1 = @IN_MY_FIELD1  AND
    MY_FIELD2 = @IN_MY_FIELD2  AND
    MY_FIELD3 = @IN_MY_FIELD3  AND 
    MY_FIELD4 = @IN_MY_FIELD4  AND
    MY_FIELD5 = @IN_MY_FIELD5  AND
    MY_FIELD6 = @IN_MY_FIELD6)
    BEGIN
        goto on_duplicate
    END

NULL = NULL은 참이 아니기 때문에.

모든 열에 IF IS NULL 문을 사용하지 않고 어떻게 확인할 수 있습니까?


INTERSECT연산자를 사용하십시오 .

당신이 모든 분야에 융통성 NULL이있는 경우에 민감하고 있습니다 :

IF      EXISTS
        (
        SELECT  MY_FIELD1, MY_FIELD2, MY_FIELD3, MY_FIELD4, MY_FIELD5, MY_FIELD6
        FROM    MY_TABLE
        INTERSECT
        SELECT  @IN_MY_FIELD1, @IN_MY_FIELD2, @IN_MY_FIELD3, @IN_MY_FIELD4, @IN_MY_FIELD5, @IN_MY_FIELD6
        )
BEGIN
        goto on_duplicate
END

당신이 UNIQUE당신의 분야에 색인 을 만들면 당신의 삶은 훨씬 더 간단해질 것입니다.


@Eric 의 대답 과 같은 줄을 따라 가지만 'NULL'기호 를 사용하지 않습니다 .

(Field1 = Field2) OR (ISNULL(Field1, Field2) IS NULL)

두 값이 non-NULL이고 서로 같거나 두 값이 모두 일치하는 경우 에만 해당 됩니다.NULL


사용 :ISNULL

ISNULL(MY_FIELD1, 'NULL') = ISNULL(@IN_MY_FIELD1, 'NULL')

그렇게 하는 것이 더 합리적이라면 'NULL'같은 것으로 변경할 수 있습니다 'All Values'.

두 개의 인수를 사용하면 테스트 할 값이 몇 개있는 경우 (예 :) 사용할 수있는 것과 ISNULL동일하게 작동합니다 . 또한 첫 번째는 null이 아닌 더 빠를 사용하지 않습니다. 그러나 나는 훨씬 더 많은 것을 의미한다고 알기 때문에 여기에서 그것을 사용했습니다.COALESCECOALESCE(@IN_MY_FIELD1, @OtherVal, 'NULL')COALESCEISNULL


MERGE를 할 때 비교가 필요했습니다.

WHEN MATCHED AND (Target.Field1 <> Source.Field1 OR ...)

추가 검사는 모든 열이 이미 동일한 행이 업데이트되지 않도록 방지하는 것입니다. 제 목적을 위해 저는 참되고 거짓이 NULL <> anyValue되고 싶었 습니다 NULL <> NULL.

솔루션은 다음과 같이 발전했습니다.

첫번째 시도 :

WHEN MATCHED AND
(
    (
        -- Neither is null, values are not equal
        Target.Field1 IS NOT NULL
            AND Source.Field1 IS NOT NULL
            AND Target.Field1 <> Source.Field1
    )
    OR
    (
        -- Target is null but source is not
        Target.Field1 IS NULL
            AND Source.Field1 IS NOT NULL
    )
    OR
    (
        -- Source is null but target is not
        Target.Field1 IS NOT NULL
            AND Source.Field1 IS NULL
    )

    -- OR ... Repeat for other columns
)

두 번째 시도 :

WHEN MATCHED AND
(
    -- Neither is null, values are not equal
    NOT (Target.Field1 IS NULL OR Source.Field1 IS NULL)
        AND Target.Field1 <> Source.Field1

    -- Source xor target is null
    OR (Target.Field1 IS NULL OR Source.Field1 IS NULL)
        AND NOT (Target.Field1 IS NULL AND Source.Field1 IS NULL)

    -- OR ... Repeat for other columns
)

세 번째 시도 시도 ( @THEn의 답변에서 영감을 얻음 ) :

WHEN MATCHED AND
(

    ISNULL(
        NULLIF(Target.Field1, Source.Field1),
        NULLIF(Source.Field1, Target.Field1)
    ) IS NOT NULL

    -- OR ... Repeat for other columns
)

ISNULL / NULLIF 논리를 사용하여 같음과 같지 발생을 테스트 할 수 있습니다.

  • 평등 : ISNULL(NULLIF(A, B), NULLIF(B, A)) IS NULL
  • 불평등 : ISNULL(NULLIF(A, B), NULLIF(B, A)) IS NOT NULL

SQL-Fiddle입니다. http://sqlfiddle.com/#!3/471d60/1


IF EXISTS(SELECT * FROM MY_TABLE WHERE 
            (MY_FIELD1 = @IN_MY_FIELD1 
                     or (MY_FIELD1 IS NULL and @IN_MY_FIELD1 is NULL))  AND
            (MY_FIELD2 = @IN_MY_FIELD2 
                     or (MY_FIELD2 IS NULL and @IN_MY_FIELD2 is NULL))  AND
            (MY_FIELD3 = @IN_MY_FIELD3 
                     or (MY_FIELD3 IS NULL and @IN_MY_FIELD3 is NULL))  AND
            (MY_FIELD4 = @IN_MY_FIELD4 
                     or (MY_FIELD4 IS NULL and @IN_MY_FIELD4 is NULL))  AND
            (MY_FIELD5 = @IN_MY_FIELD5 
                     or (MY_FIELD5 IS NULL and @IN_MY_FIELD5 is NULL))  AND
            (MY_FIELD6 = @IN_MY_FIELD6
                     or (MY_FIELD6 IS NULL and @IN_MY_FIELD6 is NULL)))
            BEGIN
                    goto on_duplicate
            END

Wordy IFNULL / COALESCE 솔루션과 비교. 그러나 NULL의 기준으로 사용할 수있는 데이터에 어떤 값이 없을지 생각할 필요없이 작동합니다.


약간의 우스꽝 스럽습니다.

    IF EXISTS(SELECT * FROM MY_TABLE WHERE 
    coalesce(MY_FIELD1,'MF1') = coalesce(@IN_MY_FIELD1,'MF1')  AND
    ...
    BEGIN
            goto on_duplicate
    END

또한 해당 coalesced값이 문제의 열에서 유효한 값이 아닌지 확인해야합니다 . 예를 들어, MY_FIELD1의 값이 'MF1'일 수있는 경우 많은 가짜 히트가 발생합니다.


같지 않은 값을 비교하려면 어떻게해야합니까? 앞서 언급 한 비교 앞에 "NOT"을 사용하는 것은 작동하지 않습니다. 내가 생각 해낼 수있는 최선의 방법은 다음과 같습니다.

(Field1 <> Field2) OR (NULLIF(Field1, Field2) IS NOT NULL) OR (NULLIF(Field2, Field1) IS NOT NULL)

필드에 기본 키를 만들고 엔진이 고유성을 적용하도록합니다. 경쟁 조건에 결함이 있으므로 IF EXISTS 논리를 수행하는 것은 어쨌든 올바르지 않습니다.


같음 비교 :

((f1 IS NULL AND f2 IS NULL) OR (f1 IS NOT NULL AND f2 IS NOT NULL AND f1 = f2))

같지 않음 비교 : 같음 비교를 부정하면 됩니다.

NOT ((f1 IS NULL AND f2 IS NULL) OR (f1 IS NOT NULL AND f2 IS NOT NULL AND f1 = f2))

장황합니까? 네, 그렇습니다. 그러나 어떤 함수도 호출하지 않기 때문에 효율적입니다. 아이디어는 술어에서 단락을 사용하여 등호 연산자 (=)가 널이 아닌 값에만 사용되는지 확인하는 것입니다. 그렇지 않으면 널이 표현식 트리에서 전파됩니다.


SET ANSI_NULLSNull 값과 함께 사용될 때 같음 (=) 및 같지 않음 (<>) 비교 연산자의 동작을 지정하기 위해 사용할 수 있습니다 .


IS NULL 또는 ISNULL을 사용해야합니다. 주변에는 정말 멀리가 없습니다.


NULLIF (TARGET.relation_id, SOURCE.app_relation_id) IS NULL 단순 솔루션


NULLIF를 확인 했습니까? http://msdn.microsoft.com/en-us/library/ms177562.aspx

참고 URL : https://stackoverflow.com/questions/1075142/how-to-compare-values-which-may-both-be-null-is-t-sql

반응형