简体   繁体   English

MySQL从同一张表获得链接结果

[英]MySQL get linked results from the same table

I can't wrap my head around a small (hopefully) MySQL question. 我无法解决一个MySQL问题(希望如此)。 I have a table called links. 我有一个称为链接的表。 It contains a customer_id field and a linked_id field and basically links customer accounts to each other where customer_id is in the lead. 它包含一个customer_id字段和一个linked_id字段,并且基本上将客户帐户彼此链接在一起,而customer_id在潜在客户中。 The newly created accounts can spawn accounts themselves and I would like to see all accounts that were created by the logged on user + all the accounts created by subaccounts. 新创建的帐户可以自己生成帐户,我想查看由登录用户创建的所有帐户+子帐户创建的所有帐户。

Table looks like this: 表看起来像这样:

+----+-------------+-----------+
| id | customer_id | linked_id |
+----+-------------+-----------+
|  1 |           1 |         5 |
|  2 |           1 |         2 |
|  3 |           1 |        11 |
|  4 |           1 |        13 |
|  5 |          13 |        14 |
|  6 |           3 |         4 |
|  7 |           7 |         8 |
+----+-------------+-----------+

So if I am logged in as user with customer_id 1 then I would like to get the userlist with linked_id 5,2,11,13 (because they are a direct connection) and linked_id 14 (because this user was created by a user who is directly connected to 1). 因此,如果我以customer_id 1的用户身份登录,那么我希望获取具有linked_id 5,2,11,13(因为它们是直接连接)和linked_id 14(因为此用户是由以下用户创建的)的用户列表直接连接到1)。

The query needs to be a subquery to get all user details. 该查询必须是子查询才能获取所有用户详细信息。 I currently have: 我目前有:

SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM links WHERE customer_id=1) or id=1;

This obviously only returns the direct connections and the user with id=1 directly. 显然,这仅返回直接连接和id = 1的用户。

Thanks to eggyal for putting me on the right track. 感谢eggyal使我走上了正确的轨道。 Seeing the relative complexity I do not feel so ashamed anymore that I could not crack it in the first go. 看到相对的复​​杂性,我再也不会感到羞愧,以至于我无法一开始就破解它。

I ended up doing some research and found some nice setups to used closure tables in mysql. 我最终做了一些研究,发现了一些用于mysql中关闭表的不错的设置。 I ended up creating a stored procedure to populate my closure table and of course the new table cust_closure. 我最终创建了一个存储过程来填充我的关闭表,当然还要填充新表cust_closure。 I renamed by links table to cust_links. 我通过链接表将其重命名为cust_links。

cust_links: cust_links:

+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| id          | int(11) | NO   | PRI | NULL    | auto_increment |
| customer_id | int(11) | YES  |     | NULL    |                |
| linked_id   | int(11) | YES  |     | NULL    |                |
+-------------+---------+------+-----+---------+----------------+

cust_closure: cust_closure:

+-------------+---------+------+-----+---------+-------+
| Field       | Type    | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| customer_id | int(11) | YES  |     | NULL    |       |
| linked_id   | int(11) | YES  |     | NULL    |       |
| distance    | int(11) | YES  |     | NULL    |       |
+-------------+---------+------+-----+---------+-------+

And then added the stored procedure: 然后添加存储过程:

CREATE PROCEDURE populate_cust_closure()
BEGIN
  DECLARE distance int;
  TRUNCATE TABLE cust_closure;
  SET distance = 0;
  -- seed closure with self-pairs (distance 0)
  INSERT INTO cust_closure (customer_id, linked_id, distance)
    SELECT customer_id, customer_id, distance
      FROM cust_links GROUP BY customer_id;

  -- for each pair (root, leaf) in the closure,
  -- add (root, leaf->child) from the base table
  REPEAT
    SET distance = distance + 1;
    INSERT INTO cust_closure (customer_id, linked_id, distance)
      SELECT cust_closure.customer_id, cust_links.linked_id, distance
        FROM cust_closure, cust_links
          WHERE cust_closure.linked_id = cust_links.customer_id
          AND cust_closure.distance = distance - 1;
  UNTIL ROW_COUNT()=0
  END REPEAT;
END // 

When I then called the stored procedure it produced: 然后,当我调用存储过程时,它产生了:

mysql> select * from cust_closure;
+-------------+-----------+----------+
| customer_id | linked_id | distance |
+-------------+-----------+----------+
|           1 |         1 |        0 |
|           3 |         3 |        0 | 
|           7 |         7 |        0 | 
|          13 |        13 |        0 | 
|           1 |         5 |        0 |
|           1 |         2 |        0 |
|           1 |        11 |        0 |
|           1 |        13 |        0 |
|          13 |        14 |        0 |
|           1 |        14 |        1 |
|           3 |         4 |        0 |
|           7 |         8 |        0 |
+-------------+-----------+----------+

So now my original query becomes: 所以现在我的原始查询变为:

SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM cust_closure WHERE customer_id=1);

Thanks again for eggyal and hope this helps someone in the future. 再次感谢您的工作,希望以后对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM