显然我错了,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/