제한 조건 3 개 중 하나만 널이 아닌지 점검하십시오.


61

FLOAT, NVARCHAR (30) 또는 DATETIME (3 개의 개별 열)의 3 가지 유형의 결과가 포함 된 (SQL Server) 테이블이 있습니다. 주어진 행에 대해 하나의 열에 만 결과가 있고 다른 열은 NULL인지 확인하고 싶습니다. 이를 달성하기위한 가장 간단한 점검 제한 조건은 무엇입니까?

이에 대한 컨텍스트는 숫자가 아닌 결과를 기존 시스템에 캡처하는 기능을 개선하려고합니다. 행당 하나 이상의 결과를 방지하기 위해 제약 조건으로 두 개의 새 열을 테이블에 추가하는 것이 가장 경제적 인 접근 방법 일 필요는 없었습니다.

업데이트 : 죄송합니다. 데이터 유형 snafu. 슬프게도 나는 결과 유형이 SQL Server 데이터 유형으로 해석되도록 의도하지 않았으며 이제는 일반적인 용어로 수정되었습니다.

답변:


72

다음은 트릭을 수행해야합니다.

CREATE TABLE MyTable (col1 FLOAT NULL, col2 NVARCHAR(30) NULL, col3 DATETIME NULL);
GO

ALTER TABLE MyTable
ADD CONSTRAINT CheckOnlyOneColumnIsNull
CHECK 
(
    ( CASE WHEN col1 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col2 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col3 IS NULL THEN 0 ELSE 1 END
    ) = 1
)
GO

24

제약 조건 내에서 세 가지 테스트를 수행해야 할 것입니다. null로 설정하려는 각 쌍에 대해 하나의 테스트와 null이 아니어야하는 열에 대해 하나씩 테스트를 수행해야합니다.

ALTER TABLE table
ADD CONSTRAINT CK_one_is_null
CHECK (
     (col1 IS NOT NULL AND col2 IS NULL AND col3 IS NULL)
  OR (col2 IS NOT NULL AND col1 IS NULL AND col3 IS NULL) 
  OR (col3 IS NOT NULL AND col1 IS NULL AND col2 IS NULL)
);

이것은 확장 할 수 없으며 9 개의 외래 키가있는 테이블이 있고 하나만 null이 아니어야합니다. @ MarkStoreySmith의 솔루션을 선호합니다.
Amir Pashazadeh

5

내장 배열 함수를 사용하는 PostgreSQL 솔루션은 다음과 같습니다 .

ALTER TABLE your_table
ADD chk_only_one_is_not_null CHECK (array_length(array_remove(ARRAY[col1::text, col2::text, col3::text], NULL), 1) = 1);

Markgrey와 mrdenny가 각각 게시 한 CASE 또는 AND / OR 솔루션보다 postgreSQL에서 이것이 더 빠른 구현입니까?
크리스 브리트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.