我有一个表,其中包含任何对象可以具有的所有属性的列表:
attr_id attr_name attr_data_type ------ ----- --------------
我有一个表[object_key]
,其中每个表object_key_id
都有一个唯一的列表,即一组 attr_id,attr_value 对。
object_key_id attr_id attr_value --------- ------- ---------- 1 1 '值 1' 1 2 '值 2' 2 1 '值 3' 2 2 'value4' 3 1 '值 1' 3 2 '值 2' 3 3 'value3'
在这种情况下,获得object_key_id
给定attr_id,attr_value
对的最佳方法是什么。
Ex: Input: [{1, 'value1'}, {2, 'value2'}]
Output: 1
建立唯一索引的最佳方法是什么,即object_key_id
对一组attr_id,attr_value
对具有唯一性?
你想要的是(确切的)Relational Division。
另见这篇文章:我们所持的分裂:关系分裂的 SQL
有几种方法可以让这样的查询解决这个问题。您可以将输入数据加载到(临时)表或使用这样的 CTE:
WITH input_data (attr_id, attr_value) AS
( SELECT *
FROM
( VALUES -- the input data.
(1, 'value1'),
(2, 'value2')
) AS i (attr_id, attr_value)
),
t AS -- all the object_key_id values.
( SELECT DISTINCT object_key_id -- if you have a separate table with those
FROM tableX -- you can use it, instead.
)
SELECT object_key_id
FROM t
WHERE NOT EXISTS -- this subquery ensures
( SELECT attr_id, attr_value -- that all input attribute/value pairs
FROM input_data -- appear for an object_key
EXCEPT
SELECT attr_id, attr_value
FROM tableX AS tt
WHERE tt.object_key_id = t.object_key_id
)
AND NOT EXISTS -- and this subquery does the reverse
( SELECT attr_id, attr_value -- i.e. the exact part of the division
FROM tableX AS tt
WHERE tt.object_key_id = t.object_key_id
EXCEPT
SELECT attr_id, attr_value
FROM input_data
) ;
Run Code Online (Sandbox Code Playgroud)
在SQL-Fiddle测试
StackOverflow 上的这个问题:How to filter SQL results in a has-many-through Relations有更多的方法可以解决它和 Postgres 的基准测试,但它不是针对确切的变化,仅针对"Division with Remainder"。查询将是相似的,但必须为确切的变化添加额外的检查/条件。
归档时间: |
|
查看次数: |
19228 次 |
最近记录: |