我正在尝试根据phone_id 获取给定user_id 的所有兄弟/连接。我的表如下所示(ad_users_id 和 ad_phones_id 是保存有关用户/电话详细信息的特定表的外键)。
id | ad_users_id | ad_phones_id | 日期_时间 |
---|---|---|---|
90 | 7177 | 19515 | |
125 | 1967 | 202 | |
235 | 7177 | 19868 | |
236 | 7177 | 19519 | |
237 | 7177 | 19516 | |
238 | 7177 | 19517 | |
239 | 7177 | 20196 | |
245 | 7177 | 19585 | |
247 | 7177 | 19701 | |
295 | 7177 | 19703 | |
342 | 3915 | 19868 | |
343 | 3915 | 19519 | |
346 | 3915 | 19516 | |
426 | 3915 | 19517 | |
368 | 3915 | 20196 | |
414 | 3915 | 19585 | |
403 | 3915 | 19701 | |
404 | 3915 | 19703 | |
1707 | 1962 | 202 | |
2124 | 1967 | 25141 | |
2129 | 9329 | 25141 |
基本上我需要获取给定 user_id 的所有直接和间接连接。我设法构建了一个 mysql 查询(递归 CTE),它看起来不太干净,但看起来它也不适用于具有多个 Phone_id 的用户,例如 user_id 7177。
WITH RECURSIVE connections (table_id, user_id, phone_id)
AS (
SELECT
CAST(ut.id AS CHAR(200)) AS table_id,
ut.ad_users_id AS user_id,
ut.ad_phones_id AS phone_id
FROM ad_phones_users_taxonomy ut
WHERE ut.ad_users_id = 7177 -- Starting user
UNION ALL
SELECT
CONCAT(c.table_id, ',', CAST(ut2.id AS CHAR(200))) AS table_id, -- CONCATENARE pentru a evita din bucla id-urile deja trase
ut2.ad_users_id AS user_id,
ut2.ad_phones_id AS phone_id
FROM ad_phones_users_taxonomy ut2
INNER JOIN connections c ON ut2.ad_phones_id = c.phone_id OR ut2.ad_users_id = c.user_id
WHERE NOT FIND_IN_SET(ut2.id, c.table_id)
LIMIT 10
)
SELECT
table_id, user_id, phone_id
FROM connections
如有任何建议,我们将不胜感激。
期望检索所有连接(直接和间接),但是对于具有多个phone_id的user_id,几乎“杀死”mysql服务器
--- 稍后编辑--- 这是创建表:
CREATE TABLE `ad_phones_users_taxonomy` (
`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,
`ad_users_id` int DEFAULT NULL,
`ad_phones_id` int DEFAULT NULL,
`data_timp` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `ad_phones_users_taxonomy` (`id`, `ad_users_id`, `ad_phones_id`, `date_time`) VALUES
(90, 7177, 19515, '2024-05-08 19:57:41'),
(125, 1967, 202, '2024-05-08 19:58:26'),
(235, 7177, 19868, '2024-05-08 20:02:52'),
(236, 7177, 19519, '2024-05-08 20:02:55'),
(237, 7177, 19516, '2024-05-08 20:02:58'),
(238, 7177, 19517, '2024-05-08 20:03:01'),
(239, 7177, 20196, '2024-05-08 20:03:04'),
(245, 7177, 19585, '2024-05-08 20:03:25'),
(247, 7177, 19701, '2024-05-08 20:03:31'),
(295, 7177, 19703, '2024-05-08 20:05:55'),
(342, 3915, 19868, '2024-05-08 20:08:21'),
(343, 3915, 19519, '2024-05-08 20:08:24'),
(346, 3915, 19516, '2024-05-08 20:08:33'),
(426, 3915, 19517, '2024-05-08 20:12:27'),
(368, 3915, 20196, '2024-05-08 20:09:36'),
(414, 3915, 19585, '2024-05-08 20:11:53'),
(403, 3915, 19701, '2024-05-08 20:11:21'),
(404, 3915, 19703, '2024-05-08 20:11:24'),
(1707, 1962, 202, NULL),
(2124, 1967, 25141, '2024-05-13 19:27:55'),
(2129, 9329, 25141, '2024-05-13 19:45:32');
对于任何 user_id:1962、1967、9329,这将是预期结果:
id | ad_users_id | ad_phones_id | 日期_时间 |
---|---|---|---|
125 | 1967 | 202 | |
1707 | 1962 | 202 | |
2124 | 1967 | 25141 | |
2129 | 9329 | 25141 |
对于任何 user_id 7177 或 3915,预期结果:
id | ad_users_id | ad_phones_id | 日期_时间 |
---|---|---|---|
90 | 7177 | 19515 | |
235 | 7177 | 19868 | |
236 | 7177 | 19519 | |
237 | 7177 | 19516 | |
238 | 7177 | 19517 | |
239 | 7177 | 20196 | |
245 | 7177 | 19585 | |
247 | 7177 | 19701 | |
295 | 7177 | 19703 | |
342 | 3915 | 19868 | |
343 | 3915 | 19519 | |
346 | 3915 | 19516 | |
426 | 3915 | 19517 | |
368 | 3915 | 20196 | |
414 | 3915 | 19585 | |
403 | 3915 | 19701 | |
404 | 3915 | 19703 |
CREATE PROCEDURE get_all (in_user_id INT)
WITH RECURSIVE
cte AS (
-- anchor part - select all rows for specified user
SELECT ad_users_id, ad_phones_id
FROM ad_phones_users_taxonomy
WHERE ad_users_id = in_user_id
-- use UNION DISTINCT which will remove duplicates
-- including the users which are processed/collected already
UNION DISTINCT
-- recursive part - add siblings
-- join one table copy by the phone then another copy by the user id
-- i.e. get a user with the same phone from t1
-- then get app phones for this user from t2
SELECT t2.ad_users_id, t2.ad_phones_id
FROM cte
JOIN ad_phones_users_taxonomy t1 USING (ad_phones_id)
JOIN ad_phones_users_taxonomy t2 ON t1.ad_users_id = t2.ad_users_id
)
-- finally retrieve original rows from gathered users
SELECT DISTINCT ad_phones_users_taxonomy.*
FROM ad_phones_users_taxonomy
JOIN cte USING (ad_users_id)
ORDER BY id;