【问题标题】:How to create a cluster of related entries in a many-to-many-relation?如何在多对多关系中创建一组相关条目?
【发布时间】:2020-12-14 05:39:57
【问题描述】:

我有一个订阅用户表,其中包含联系人 ID 和订单 ID。多个联系人可以链接到一个订单,一个联系人可以链接到多个订单。我正在尝试接受一个给定的订单,查看该订单的用户,确定与这些用户中的任何一个相关联的任何其他订单,并将它们链接为一个公司,如下表所示:

【问题讨论】:

  • 我认为,您要查找的内容不可能在一个 SQL 查询中完成。首先,因为我认为没有办法让 SQL 自动命名您的公司。如果您避免这种情况,您可能会从一个条目开始,查找该公司中的所有联系人,然后在没有公司的情况下获取另一个条目并重复此操作,直到您没有没有公司的条目。但即便如此,我认为你需要某种递归来解决你的问题。一个建议:
  • SELECT DISTINCT contactID FROM a WHERE orderID IN (SELECT orderID FROM a WHERE contactID IN (SELECT contactID FROM a WHERE orderID = 5))
  • 感谢您对 Jere 的帮助

标签: sql many-to-many recursive-query


【解决方案1】:

显然我错了,SQL 确实提供了解决您问题的方法。这是我的解决方案。它没有针对运行时效率进行优化 - 如果有必要,我可以再看看它:

with recursive 
    incompany(contact, order1, order2) 
        as (select contact, o1.orderID as order1, o2.orderID as order2 
            from orders o1 join orders o2 using (contact) 
            union 
            select o1.contact, inc.order1, o2.orderID as order2 
            from incompany as inc, orders as o1, orders as o2 
            where inc.order2=o1.orderID and o1.contact=o2.contact) 

select contact, sum(order1) as MyNewCompanyID from 
    (select distinct contact, order1 from incompany) as foo 
    group by contact;

在第一部分中,我定义了一个递归查询incompany,它完成了大部分工作并将同一公司中另一个联系人使用的每个orderID 分配给该联系人。所以select * from incompany; 本身会返回下表:

+---------+--------+--------+
| contact | order1 | order2 |
+---------+--------+--------+
| a       |      1 |      1 |
| a       |      1 |      2 |
| a       |      2 |      1 |
| a       |      2 |      2 |
| a       |      3 |      1 |
| a       |      3 |      2 |
| b       |      1 |      1 |
| b       |      2 |      1 |
| b       |      3 |      1 |
| c       |      1 |      1 |
| c       |      2 |      1 |
| c       |      3 |      1 |
| d       |      1 |      2 |
| d       |      1 |      3 |
| d       |      2 |      2 |
| d       |      2 |      3 |
| d       |      3 |      2 |
| d       |      3 |      3 |
| e       |      4 |      4 |
| e       |      4 |      5 |
| e       |      5 |      4 |
| e       |      5 |      5 |
| f       |      4 |      4 |
| f       |      5 |      4 |
| g       |      4 |      5 |
| g       |      5 |      5 |
+---------+--------+--------+

查询的第二部分基本上只是将此表缩短到必要的最小值,然后创建一种新的“公司 ID”(MyNewCompanyID) 作为该公司使用的所有订单的总和。在您的示例中,它返回下表:

+---------+----------------+
| contact | MyNewCompanyID |
+---------+----------------+
| a       |              6 |
| b       |              6 |
| c       |              6 |
| d       |              6 |
| e       |              9 |
| f       |              9 |
| g       |              9 |
+---------+----------------+

with 部分的作用

在第一部分中,我定义了一个临时视图之类的东西,以后我可以像普通表一样访问它。在内部,它必须首先包含一个常规查询,然后由第二个查询联合,允许递归访问自身。

如果你想进一步了解这种递归,我推荐这两个视频:

编辑

要为每个公司分配一个唯一编号,您可能应该使用row_number(),如下所述:https://www.sqlservertutorial.net/sql-server-window-functions/sql-server-row_number-function/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2019-10-11
    • 2021-03-12
    • 2022-10-25
    • 1970-01-01
    相关资源
    最近更新 更多