我有两个表(entity
和 kind
)以及一个 n:m 表(entity_kind
)。
CREATE TABLE
entity
(
entity_id INT
, name NVARCHAR(100)
, PRIMARY KEY(entity_id)
)
CREATE TABLE
kind
(
kind_id INT
, name NVARCHAR(100)
, PRIMARY KEY(kind_id)
)
CREATE TABLE
entity_kind
(
entity_id INT
, kind_id INT
, PRIMARY KEY(entity_id, kind_id)
)
测试数据:
INSERT INTO
entity
VALUES
(1, 'Entity A')
, (2, 'Entity B')
, (3, 'Entity C')
INSERT INTO
kind
VALUES
(1, 'Kind 1')
, (2, 'Kind 2')
, (3, 'Kind 3')
, (4, 'Kind 4')
INSERT INTO
entity_kind
VALUES
(1, 1)
, (1, 3)
, (2, 1)
, (2, 2)
, (3, 4)
到目前为止我的代码:
DECLARE
@selected_entities
TABLE
(
entity_id INT
)
DECLARE
@same_kinds BIT;
INSERT INTO
@selected_entities
VALUES
(1), (2)
-- Missing code here
SELECT
@same_kinds AS "same_kinds"
表 var @selected_entities
填充了应比较的实体。
逻辑变量@same_kinds
应指示所选实体是否分配了完全相同的种类。
我怎样才能实现这个目标?
最佳答案
这是一个比较两组事物类型的问题。我要显示的查询给出了所有对以及一个标志。通过将前两个 entity
表更改为要比较的 ID 表,您可以轻松合并比较子查询。
该查询由几个部分组成。首先,它从实体表中生成所有实体对。这很重要,因为这甚至会拾取没有与之关联的“种类”的实体。您需要一个标志,而不仅仅是匹配的列表。
然后逻辑的核心是在实体种类表上与“kind”匹配进行自连接。然后由两个实体聚合。结果是两个实体共享的类型的计数。
最终逻辑是将这个计数与每个实体上的“种类”计数进行比较。如果所有这些计数都相同,则实体匹配。如果没有,他们就不会。此方法确实假设 entity_kinds
中没有重复项。
select e1.entity_id as e1, e2.entity_id as e2,
(case when count(ek1.entity_id) = max(ek1.numkinds) and
count(ek2.entity_id) = count(ek1.entity_id) and
max(ek1.numkinds) = max(ek2.numkinds)
then 1
else 0
end) as IsSame
from entity e1 join
entity e2
on e1.entity_id < e2.entity_id left outer join
(select ek.*, count(*) over (partition by entity_id) as numkinds
from entity_kind ek
) ek1
on e1.entity_id = ek1.entity_id left outer join
(select ek.*, count(*) over (partition by entity_id) as numkinds
from entity_kind ek
) ek2
on e2.entity_id = ek2.entity_id and
ek2.kind_id = ek1.kind_id
group by e1.entity_id, e2.entity_id;
SQL fiddle 是 here .
关于sql - 如何比较 n :m assignments?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21510571/