ここでの考え方は、3つの異なるタプル制約として実装できる3つのビジネスルールがあるということです(つまり、テーブルのすべての行に対してfalseではありません)。
id
等しくなければなりlang
ません(論点先取、計算列を作成してみませんか?)。
もしそうなら、そうletter
でなければ'E'
なりlang
ません1
(私はあなたの質問にあなたが'e'
代わりに言ったタイプミスがあると思います'E'
)。
もしそうなら、そうletter
でなければ'F'
なりlang
ません2
(私はあなたの質問にあなたが2
代わりに言ったタイプミスがあると思います'F'
)。
制約は、他のデータについて「何も言うことはありません」(たとえば、いつletter
であるか'X'
)、これを通過させることができます。
3つのタプル制約はすべて、制約検証クエリとして連言標準形で記述できます。
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 ) )
書き換え法の適用(ド・モルガンの法則と二重否定法)eg
SELECT * FROM T
WHERE id <> lang
OR ( letter = 'E' AND lang <> 1 )
OR ( letter = 'F' AND lang <> 2 )
論理的に言えば、これはオプティマイザーにとってより良いはずです。なぜなら、上記が矛盾するためには、すべての分離メンバーが偽でなければならないからです(言い換えると、データが「悪い」と見なされるには、1つのOR'ed句だけが真になります) 。実際には(理論的には?)、オプティマイザーはとにかくそのような書き換えを実行できるはずです!
ps nullは論理に悪いです-それらを避けてください!
サンプルデータを含む私のテストコードは次のとおりです。
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 );