听起来你真正拥有的是规则和规则集。以这种方式对其进行建模不仅会使这种特定的编码更加简单,而且当您决定需要 16 列时,还会使模型可扩展。
例如:
CREATE TABLE Rules (
rule_id INT NOT NULL,
rule_category CHAR(1) NOT NULL, -- This is like your column idea
rule_int_value INT NULL,
rule_str_value VARCHAR(20) NULL,
CONSTRAINT PK_Rules PRIMARY KEY CLUSTERED (rule_id),
CONSTRAINT CK_Rules_one_value CHECK (rule_int_value IS NULL OR rule_str_value IS NULL)
)
CREATE TABLE Rule_Sets (
rule_set_id INT NOT NULL,
rule_id INT NOT NULL,
CONSTRAINT PK_Rule_Sets PRIMARY KEY CLUSTERED (rule_set_id, rule_id)
)
一些符合您给定规则的数据:
INSERT INTO Rules (rule_id, rule_category, rule_int_value, rule_str_value)
VALUES (1, 'A', 50, NULL)
INSERT INTO Rules (rule_id, rule_category, rule_int_value, rule_str_value)
VALUES (2, 'A', 51, NULL)
INSERT INTO Rules (rule_id, rule_category, rule_int_value, rule_str_value)
VALUES (3, 'B', NULL, 'xyz')
INSERT INTO Rules (rule_id, rule_category, rule_int_value, rule_str_value)
VALUES (4, 'C', 123, NULL)
INSERT INTO Rules (rule_id, rule_category, rule_int_value, rule_str_value)
VALUES (5, 'C', 456, NULL)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (1, 1)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (2, 2)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (2, 3)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (3, 2)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (3, 4)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (4, 3)
INSERT INTO Rule_Sets (rule_set_id, rule_id) VALUES (4, 5)
确认您期望的相同答案的测试脚本:
DECLARE
@a INT,
@b VARCHAR(20),
@c INT
SET @a = 50
SET @b = 'xyz'
SET @c = 456
SELECT DISTINCT
rule_set_id AS failed_rule_set_id
FROM
Rule_Sets RS
WHERE
NOT EXISTS (SELECT * FROM Rules R WHERE R.rule_id = RS.rule_id AND @a = R.rule_int_value) AND
NOT EXISTS (SELECT * FROM Rules R WHERE R.rule_id = RS.rule_id AND @b = R.rule_str_value) AND
NOT EXISTS (SELECT * FROM Rules R WHERE R.rule_id = RS.rule_id AND @c = R.rule_int_value)
如果您可以以基于集合的形式而不是作为单个参数来呈现输入数据,那么最终的 SQL 语句可以更加动态,并且在您添加其他列时不必增长。