我无法绕过一个小的(希望)MySQL问题。我有一个叫做链接的表。它包含customer_id字段和linked_id字段,并且基本上将客户帐户链接到customer_id处于领先地位的彼此。新创建的帐户可以自己生成帐户,我希望查看登录用户创建的所有帐户+子帐户创建的所有帐户。
表格如下:
+----+-------------+-----------+
| 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 |
+----+-------------+-----------+
因此,如果我以customer_id 1的用户身份登录,那么我希望获得带有linked_id 5,2,11,13的用户列表(因为它们是直接连接)和linked_id 14(因为此用户是由直接连接到1)的用户。
查询需要是子查询才能获取所有用户详细信息。我目前有:
SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM links WHERE customer_id=1) or id=1;
这显然只返回直接连接和id = 1的用户。
答案 0 :(得分:1)
感谢eggyal让我走上正轨。看到相对的复杂性,我不再感到羞耻,因为我无法在第一时间破解它。
我最终做了一些研究,发现在mysql中使用了闭包表的一些不错的设置。我最终创建了一个存储过程来填充我的闭包表,当然还有新表cust_closure。我通过链接表重命名为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:强>
+-------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+-------+
| customer_id | int(11) | YES | | NULL | |
| linked_id | int(11) | YES | | NULL | |
| distance | int(11) | YES | | NULL | |
+-------------+---------+------+-----+---------+-------+
然后添加了存储过程:
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 //
当我调用它生成的存储过程时:
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 |
+-------------+-----------+----------+
所以现在我的原始查询变为:
SELECT username, firstname, lastname, email, active, level FROM customers WHERE id
IN (SELECT linked_id FROM cust_closure WHERE customer_id=1);
再次感谢eggyal,并希望将来有人帮助。