我有一张表大致如下:
CREATE TABLE t_table (
f_userid BIGINT NOT NULL
,f_groupaid BIGINT
,f_groupbid BIGINT
,f_groupcid BIGINT
,f_itemid BIGINT
,f_value TEXT
);
这些组是正交的,因此除了表中的每个条目都有一个用户 ID 之外,不能隐含任何层次结构。任何列都没有唯一性。
例如,一个简单的设置可能是:
INSERT INTO t_table VALUES (1, NULL, NULL, NULL, NULL, 'Value for anything by user 1');
INSERT INTO t_table VALUES (1, 5, 2, NULL, NULL, 'Value for anything by user 1 in groupA 5 groupB 2');
INSERT INTO t_table VALUES (1, 4, NULL, 1, NULL, 'Value for anything by user 1 in groupA 5 and groupC 1');
INSERT INTO t_table VALUES (2, NULL, NULL, NULL, NULL, 'Value for anything by user 2');
INSERT INTO t_table VALUES (2, 1, NULL, NULL, NULL, 'Value for anything by user 2 in groupA 1');
INSERT INTO t_table VALUES (2, 1, 3, 4, 5, 'Value for item 5 by user 2 in groupA 1 and groupB 3 and groupC 4');
对于任何给定的 user/groupA/groupB/groupC/item 集,我希望能够获得表中适用的最具体的项目。如果给定集合中的任何一个为 NULL,则它只能匹配表中包含 NULL 的相关列。例如:
// Exact match
SELECT MostSpecific(1, NULL, NULL, NULL, NULL) => "Value for anything by user 1"
// Match the second entry because groupC and item were not specified in the table and the other items matched
SELECT MostSpecific(1, 5, 2, 3, NULL) => "Value for anything by user 1 in groupA 5 groupB 2"
// Does not match the second entry because groupA is NULL in the query and set in the table
SELECT MostSpecific(1, NULL, 2, 3, 4) => "Value for anything by user 1"
这里显而易见的方法是让存储过程处理参数并找出哪些是 NULL 而不是,然后调用适当的 SELECT 语句。但这似乎非常低效。有没有更好的方法来做到这一点?