MySQL запрос с использованием переменной

Ilya Indigo

Новичок
Имеем таблицу с упрощённой структурой
PHP:
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;
имеем дамп
PHP:
INSERT INTO `ilya_dir_cat`
	(`id`,`pid`,`title`)
VALUES
	(1,'0','c1'),
	(2,'1','c1.1'),
	(3,'1,2','c1.1.1'),
	(4,'0','c2'),
	(49,'4','c21'),
	(50,'4,49','c211'),
	(51,'4,49,50','c2111'),
	(56,'0','c3'),
	(57,'56','c31'),
	(58,'56,57','c311'),
	(59,'56,57,58','c3111'),
	(60,'56,57,58,59','c31111'),
	(61,'0','Cat 4'),
	(62,'61','Subcat 4.1'),
	(63,'61','Subcat 4.2'),
	(64,'61','Subcat 4.3'),
	(65,'61','Subcat 4.4'),
	(66,'0','Cat 5'),
	(67,'0','Cat 6');
Таблица представляет собой каталог с неограниченной вложенностью, где в поле `pid` самый первый родитель имеет значение 0, а `pid` его дочерние элементы содержат `id` всех его родителей разделённые запятыми, начиная с самого первого.
Задача 1а
Имея `id` любого элемета, самого верхнего родителя (56) или его дочерних элементов (57,58,59,60) вернуть `id` его самого первого родителя (56) (Для самого верхнего родителя это `id` для его дочерних элементов это первая цифра в `pid`)
Решается следующим образом
PHP:
SELECT ABS(CASE `pid` WHEN 0 THEN `id` ELSE `pid` END)`id` FROM `ilya_dir_cat` WHERE `id`=59;
(по `id`=59 возврашает 56)
Задача 1б
Имея `id` первого родителя (56) получить все его дочерние элементы, у которых `pid` начинается с 56 (57,58,59,60)
Решается следующим образом
PHP:
SELECT * FROM `ilya_dir_cat` WHERE `pid`=56 ORDER BY `pid`,`id`;
А теперь суть вопроса...
Как это сделать одним запросом?
PHP:
SELECT @id:=ABS(CASE WHEN i.pid=0 THEN i.id ELSE i.pid END)`i`,c.* FROM (SELECT * FROM `ilya_dir_cat` WHERE `id`=59)`i` JOIN `ilya_dir_cat`AS`c` ON c.pid=@id ORDER BY c.pid,c.id;
Пытался сделать так, но переменная @id наверно слишком поздно вычисляется и возвращает NULL.
Возможно ли это сделать одним запросом, и если возможно, то как?
 

Ilya Indigo

Новичок
Упростив себе задачу всё же написал подзапросом
PHP:
SELECT * FROM `ilya_dir_cat` WHERE `pid`=(SELECT CASE `pid` WHEN 0 THEN `id` ELSE `pid` END+0 FROM `ilya_dir_cat` WHERE `id`=59) ORDER BY `pid`,`id`;
Но всё же изначально предпологал вывести не только дочерние элементы, но и родителя и что бы не лепить лишний аналогичный под запрос в условии WHERE `id`=() || `pid`=() хотел использовать переменную, и собственно не совсем понял почему у меня не получилась её использовать и как именно я должен был её использовать в этом случае?
SUBSTRING_INDEX() поможет
Вы наверно имели ввиду SUBSTRING_INDEX(`pid`,',',1) (`56,57,58,59...` ---> '56') - способ интересный, но с ним то как раз проблем не было я нащёл, как мне кажется, более быстрый и приемлемый способ просто перевести из строка в число, самый правильный способ CAST(`pid` AS INT); но так же можно ABS(`pid`); или проще всего `pid`+0;
Проблема заключается в том, как правильно мне использовать переменную в запросе, если условие было бы WHERE `id`=() || `pid`=()?
 
Сверху