SQL-запрос для MySQL (MariaDB) 5.5.23 Подсчёт кол-ва вхождений символа в строку.

Ilya Indigo

Новичок
Имею упрощённый вид каталог с неограниченным уровнем вложенности
Код:
CREATE TABLE `ilya_dir_cat`
(
    `id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `pid` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `title` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
)
ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
Код:
Первый уровень с `id`=1 `pid`='0'
Первый уровень с `id`=2 `pid`='0'
Второй уровень родителя с `id`=1 - `id`=3 `pid`='1'
Второй уровень родителя с `id`=1 - `id`=4 `pid`='1'
Третий уровень родителя с `id`=3 - `id`=5 `pid`='1,3'
Четвёртый уровень родителя с `id`=5 - `id`=6 `pid`='1,3,5'
Смысл в том что `pid` (parent id) через запятую последовательно содержит `id` всех своих предков, начиная с самого первого.

Задача состоит в том, что бы по-мимо основного вывода, нужно посчитать и вывести уровень каждого элемента, начиная с нуля первый - 0, второй - 1, третий - 2 и т.д.
У меня сразу возникла идея проверить на 0 и если больше, то прибавить к стоке ',0' И подсчитать кол-во вхождений запятой и вернуть или его или 0.
Но такой функции для MySQL я не обнаружил. может плохо искал или в новой версии 5.5 есть?
Нащёл интересную функцию INTERVAL она выполняет то что мне нужно, но при условии что `id` уменьшаются, а не увеличиваются, как у меня при этом использование REVERSE не подходит, так как если строка '56,57,58,59,60' вместо ожидаемой '60,59,58,57,56' я получу '06,95,85,75,65' что меня не устроит :(
Возможно это осуществить адекватными средствами MySQL 5.5, кроме как JOIN-ить с подсчётом длины и первого вхождения со смещением и посчётов этих смещений и прочего?
Спедствами PHP я это легко могу осуществит, но хотелось бы это сделать именно средствами MySQL
 

NeD

Новичок
PHP:
 ( ( CHAR_LENGTH(`pid`) - CHAR_LENGTH( REPLACE(`pid`,',', '' ) ) ) DIV CHAR_LENGTH( ',' ) )  AS `level`
Вот так можно посчитать кол-во вхождений символа в строку
 

Ilya Indigo

Новичок
NeD Большое спасибо за идею :))
С функцией вы конечно перемудрили, хотя понимаю, что она для универсального случая подсчёта вхождения, но обрезанный вариант, мне прекрасно подошёл :))
PHP:
LENGTH(`pid`)+1-LENGTH(REPLACE(`pid`,',',''))`pos`;
 

Redjik

Джедай-мастер
а почему не nested set?
кстати для adjacency list делал такое - просто кешировал всех детей
 

Ilya Indigo

Новичок
а почему не nested set?
http://www.woweb.ru/publ/41-1-0-464?lMXCSd
Это, как по мне, слишком навороченная система.
Для моих нужд вполне сойдёт моя система хранения `id` в числе и `pid` в строке, которая будет гораздо быстрее выбираться и редактироваться, вообще без JOIN-ов, и хранит меньше данных в таблице и с виду, при просмотре через БД, куда более понятна, а так же с учётом того что иерархию дочерних элементов, за исключением удаления самого вложенного, мне менять не нужно.
 

Redjik

Джедай-мастер
Ilya Indigo
Да нет в ней ничего навороченного, мне не понятен страх перед лишним JOIN...
Ручками то можно ничего не писать же... В сети масса классов для авто Nested Sets, даже с транзакциями.
 
Сверху