おおよそ次のような表があります。
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');
ユーザー/グループA/グループB/グループC/アイテムの特定のセットについて、適用されるテーブルで最も具体的なアイテムを取得できるようにしたいと考えています。指定されたセットのいずれかが 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 ステートメントを呼び出すことです。しかし、これは非常に効率が悪いようです。これを行うより良い方法はありますか?