【问题标题】:Commonality in many to many relationship SQL query多对多关系SQL查询的共性
【发布时间】:2021-08-27 09:58:19
【问题描述】:

如果我的代理可以具有许多属性,反之亦然,在联结表中定义,我将如何查询顶级代理(与其他两个代理具有至少两个共同属性的代理。)

agent

id
1
2
3
4
5

properties

id
1
2
3
4
5
6

agent_properties

agent_id property_id
1 1
1 2
1 3
2 2
2 3
3 1
3 3
3 5
4 3
4 4
4 6
5 1
5 2
5 5
6 4
6 6
Example:
Agent 1 (propr1, propr2, propr3),
Agent 2 (propr2, propr3),
Agent 3 (propr1, propr3, propr5)
Agent 4 (propr3, propr4, propr6)
Agent 5 (propr1, propr2, propr5)
Agent 6 (propr4, propr6)

所以查询应该返回代理 1、代理 3、代理 5

如果有人可以展示如何使用 Laravel Eloquent 做到这一点,那就太好了。

【问题讨论】:

  • 您能否提供样本数据模板、预期结果以及您尝试了什么?您可以使用:sqlfiddle.com/#!9
  • 你有多少房产?如果您的属性少于 32 个,这可能是一个解决方案。

标签: mysql laravel eloquent


【解决方案1】:

解决方案是使用位。

首先您应该在表properties 中添加一个新列,并将这个新列命名为bin_value。此列中的值必须是每个属性的唯一值,并且是 2 的幂。在您的情况下是:

id bin_value
1 1
2 2
3 4
4 8
5 16
6 32

其次,在agent 表中添加一个名为properties 的新列并运行以下更新查询:

UPDATE agent AS a
INNER JOIN (
    SELECT ap.agent_id, SUM(p.bin_value) AS bin_properties
    FROM agent_properties AS ap
    INNER JOIN properties AS p ON p.id = ap.property_id
    GROUP BY ap.agent_id
) AS b ON a.id = b.agent_id
SET a.properties = b.bin_properties
;

第三,使用位函数运行查询,它可以帮助您找到与至少 2 个其他代理具有至少 2 个共享属性的代理:

SELECT a1.agent_id
, a1.name
, COUNT(*) AS total_other_agents
FROM agent AS a1
INNER JOIN agent AS a2 ON a1.id != a2.id 
    AND BIT_COUNT(a1.properties & a2.properties) >= 2 -- at least 2 shared properties
GROUP BY a1.id
HAVING total_other_agents >= 2 -- at least 2 other agents
ORDER BY total_other_agents DESC, a1.name
;

如果您有大量属性,请尝试在bin_value 中设置值,如下所示:

UPDATE properties
SET bin_value = BINARY(POWER(2, id-1))
;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2012-07-30
    相关资源
    最近更新 更多