mysql cte递归获取所有兄弟姐妹

问题描述 投票:0回答:1

我正在尝试根据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
mysql recursion common-table-expression
1个回答
0
投票
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;

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.