Как отсортировать таблицу mysql указанным способом c - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть следующая таблица в результате запроса:

    SELECT f.id, f.parent_id, f.name, f.fullpath, 
    FROM folders f
    WHERE fullpath LIKE CONCAT("%", 'fs-3', "%") 
    ORDER BY fullpath ASC, name ASC;   
id      parent_id       name        fullpath
-----------------------------------------------------------------
fs-3    null            root        fs-3
fs-d    fs-3            test        fs-3/fs-d
fs-5    fs-d            test        fs-3/fs-d/fs-5
fs-g    fs-3            test3       fs-3/fs-g
fs-2    fs-g            test        fs-3/fs-g/fs-2
fs-s    fs-2            test        fs-3/fs-g/fs-2/fs-s
fs-y    fs-3            test2       fs-3/fs-y
fs-4    fs-y            test        fs-3/fs-y/fs-4

Таблица отсортирована по

ORDER BY fullpath ASC, name ASC

Желаемый результат: name column получает отсортировано таким образом, что test3 идет после test2 при сохранении сортировки fullpath. Но я не знаю, как этого добиться?

id      parent_id       name        fullpath
-----------------------------------------------------------------
fs-3    null            root        fs-3
fs-d    fs-3            test        fs-3/fs-d
fs-5    fs-d            test        fs-3/fs-d/fs-5
fs-y    fs-3            test2       fs-3/fs-y
fs-4    fs-y            test        fs-3/fs-y/fs-4
fs-g    fs-3            test3       fs-3/fs-g
fs-2    fs-g            test        fs-3/fs-g/fs-2
fs-s    fs-2            test        fs-3/fs-g/fs-2/fs-s

Ответы [ 3 ]

1 голос
/ 16 февраля 2020

Если у вас MySql 8.0 или больше, чем:

WITH RECURSIVE folders_path (id, name, path) AS
(
  SELECT id, name, name as path
    FROM folders
    WHERE parent_id IS NULL
  UNION ALL
  SELECT f.id, f.name, CONCAT(fp.path, '/', f.name)
    FROM folders_path fp JOIN folders AS f
      ON fp.id = f.parent_id
)
SELECT f.id, f.parent_id, f.name, fp.path 
    FROM folders f JOIN folders_path fp on f.id = fp.id
    WHERE fullpath LIKE CONCAT("%", 'fs-3', "%")
    ORDER BY fp.path;   

См. DB Fiddle

Примечание: В приведенной выше DB Fiddle я не удосужился добавьте столбец fullpath, поскольку в качестве добавленных примеров данных уже удовлетворено условие WHERE.

1 голос
/ 16 февраля 2020

Поскольку вы хотите отказаться от хранимых функций , вам необходимо перестроить путь, используя имена вместо идентификаторов, используя MySQL 8.0 рекурсивный запрос.

WITH RECURSIVE cte AS (
  SELECT f.id, f.parent_id, f.name, f.fullpath
       , CAST(f.name AS CHAR(50)) AS namepath
    FROM folders f
   WHERE f.id = 'fs-3'
  UNION ALL
  SELECT f.id, f.parent_id, f.name, f.fullpath
       , CONCAT(cte.namepath, '/', f.name) AS namepath
    FROM cte
    JOIN folders f ON f.parent_id = cte.id
)
SELECT id, parent_id, name, fullpath
  FROM cte
 ORDER BY namepath

См. DB Fiddle для демонстрации.

0 голосов
/ 16 февраля 2020

Вы можете сделать это с помощью условной сортировки:

select f.* 
from folders f
where fullpath like concat("%", 'fs-3', "%")
order by
  case 
    when exists (
      select 1 from folders  
      where name = 'test2'
      and f.fullpath like concat(fullpath, '%')
    ) then 1
    when exists (
      select 1 from folders  
      where name = 'test3'
      and f.fullpath like concat(fullpath, '%')
    ) then 2
  end,
  f.fullpath,
  f.name

См. Демоверсию . Результаты:

| id   | parent_id | name  | fullpath            |
| ---- | --------- | ----- | ------------------- |
| fs-3 | null      | root  | fs-3                |
| fs-d | fs-3      | test  | fs-3/fs-d           |
| fs-5 | fs-d      | test  | fs-3/fs-d/fs-5      |
| fs-y | fs-3      | test2 | fs-3/fs-y           |
| fs-4 | fs-y      | test  | fs-3/fs-y/fs-4      |
| fs-g | fs-3      | test3 | fs-3/fs-g           |
| fs-2 | fs-g      | test  | fs-3/fs-g/fs-2      |
| fs-s | fs-2      | test  | fs-3/fs-g/fs-2/fs-s |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...