Передать значения из Select в CROSS JOIN CTE в MySQL - PullRequest
0 голосов
/ 20 марта 2019

У меня есть таблица в базе данных MySQL, а именно «пользователи»

CREATE TABLE `users` (
  `user_id` int NOT NULL,
  `name` varchar(100) NOT NULL,
  `parent_user_id` int
);

INSERT INTO `users` (`user_id`, `name`, `parent_user_id`) VALUES
(1, 'John', null), 
(2, 'Emma', 1), 
(3, 'Watson', 2),
(4, 'Peter', 3), 
(5, 'Rose', 1), 
(6, 'Harry', 4),
(7, 'Jim', 6), 
(8, 'Jack', 5), 
(9, 'Josh', 8),
(10, 'Jem', 9);

Мне нужно запросить у таблицы users, что большинство предков не пользователь root (то есть пользователь root 1)

Ожидаемый результат:

user_id     name          root_parent_user_id     root_parent_user_name
______________________________________________________________
1           John          null               null
2           Emma          1                  John
3           Watson        2                  Emma
4           Peter         2                  Emma
5           Rose          1                  John
6           Harry         2                  Emma
7           Jim           2                  Emma
8           Jack          5                  Rose
9           Josh          5                  Rose
10          Jem           5                  Rose

Логика для требования :

Случай № 1 - если идентификатор родительского элемента равенNULL:

  • У пользователя нулевой parent_id, так что это самый первый пользователь, и у него нет родителя / предка

Случай № 2: - Если идентификатор родительского элемента равен 1 (это означает, что пользователь был создан самым первым предком)

  • У пользователя есть parent_id 1, поэтому нам нужно взять родительский элемент 1

Случай № 3 : - Если идентификатор родительского элемента равен N (это означает, что пользователь был создан N-м дочерним элементом случая № 2)

  • Пользователь имеетparent_id n (например, user_id равен 6, а n равно 4), поэтому нам нужно найти корневого родителя, который был создан самым первым предком, и, наконец, ответ «user_id: 2» (т. е. Эмма).

Я попробовал следующий код:

SELECT * FROM users USR
CROSS JOIN (
WITH RECURSIVE cte (user_id, name, parent_user_id) AS
    (
      SELECT user_id, name, parent_user_id
        FROM users
        WHERE user_id = USR.user_id
      UNION ALL
      SELECT c.user_id, c.name, c.parent_user_id
        FROM cte AS cp JOIN users AS c
          ON cp.parent_user_id = c.user_id
    )
    SELECT * FROM cte where parent_user_id = 1
) PUSR ON 1 = 1;

I с ошибкой Код ошибки: 1054. Неизвестный столбец 'USR.user_id' в 'выражении where'

Пожалуйста, помогите мне, как передать значение в CTE, где условие из вышеприведенного запроса и как добиться запрошенного вывода.

1 Ответ

1 голос
/ 20 марта 2019

Я не думаю, что это лучший подход, так как он будет стоить вам много времени при обработке и может стать кошмаром для последующего обслуживания вашего приложения.Вы должны просто сохранить пользователя root для каждого пользователя в базе данных (именно так большинство древовидных систем справляются с этим).Ваша структура таблицы станет такой: user_id |имя |parent_user_id |root_user_id

Если вы действительно хотите продолжать таким образом, я бы посоветовал вам проверить это (вам просто нужно добавить к нему условие «не пользователь 1 root»): https://dba.stackexchange.com/questions/7147/find-highest-level-of-a-hierarchical-field-with-vs-without-ctes/7150

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...