나는이 해당 기준을 충족 레코드를 제외 할 것을 생각 여기에 세 개의 별개의 튜플 제약 조건으로 구현 될 수있는 세 가지 비즈니스 규칙이 있습니다 (즉, 테이블의 모든 행에 대해 false가 아님).
id
과 은 같아야합니다 (질문을하기, 왜 계산 열을 만들지 않겠습니까?). letter
이 'E'
경우
다음 lang
(난 당신이 'e'
대신 'E'
말했다 질문에 오타가 있다고 가정) 1
해야합니다. letter
이 'F'
경우
다음 lang
(난 당신이 2
대신 'F'
말했다 질문에 오타가 있다고 가정) 2
해야합니다.
제약은 다른 데이터에 대해 '할 말이 아무것도하지 않는다'(예를 들어 letter
이 'X'
경우)이 통과 할 수 있습니다.
세 튜플 제약
는 제약 검증 쿼리로 결합하는 일반적인 형태로 쓸 수있다 :
SELECT * FROM T
WHERE id = lang
AND (letter <> 'E' OR lang = 1)
AND (letter <> 'F' OR lang = 2)
제약 조건을 위반하는 데이터는 단순히 (의사 관계 대수에) 표시 할 수 있습니다 :
T MINUS (constraint validation query)
SQL에서
는 :
SELECT * FROM T
EXCEPT
SELECT * FROM T
WHERE id = lang
AND (letter <> 'E' OR lang = 1)
AND (letter <> 'F' OR lang = 2)
할 수있을 것이 좋다 하나의 선택 쿼리가 선택의 DBMS에 접착제처럼 실행될 경우를 대비하여 술어를 다시 작성하십시오! 상기 내용은 예를 들면 다음과 같이 재 기입 될 수있다.
SELECT * FROM T
WHERE NOT (id = lang
AND (letter <> 'E' OR lang = 1)
AND (letter <> 'F' OR lang = 2))
재 작성법 적용 (De Morgan과 double negative).
SELECT * FROM T
WHERE id <> lang
OR (letter = 'E' AND lang <> 1)
OR (letter = 'F' AND lang <> 2)
가 논리적이 때문에 위의 모든 분리 된 회원이 (거짓 다른 방법을 넣어해야합니다 모순 할 수 최적화에 더해야한다, 말하기, 그것은 단지 데이터에 대한 사실 하나의 OR 연산 절을합니다 '나쁜'것으로 간주 됨). 실제로 (이론적으로) 옵티마 이저
은과 같은 재 작성을 수행 할 수 있어야합니다!
p.s. nulls은 논리에 좋지 않습니다 - 피하십시오!
여기에 샘플 데이터를 내 테스트 코드는 다음과 같습니다
WITH Nums AS (SELECT *
FROM (VALUES (0), (1), (2)) AS T (c)),
Chars AS (SELECT *
FROM (VALUES ('E'), ('F'), ('X')) AS T (c)),
T AS (SELECT N1.c AS id, N2.c AS lang,
C1.c AS letter
FROM Nums AS N1, Nums AS N2, Chars AS C1)
SELECT * FROM T
EXCEPT
SELECT * FROM T
WHERE id = lang
AND (letter <> 'E' OR lang = 1)
AND (letter <> 'F' OR lang = 2);
귀하의 조건이 이해가되지 않습니다. 질문을 수정하십시오. – Icarus