powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / рекурсивная функция (процедура)
43 сообщений из 43, показаны все 2 страниц
рекурсивная функция (процедура)
    #35301291
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток вам!
Насколько я понял, рекурсию простым запросом не реализовать, и надо писать хранимую процедуру(функцию) для этого. В этом и прошу собственно у вас помощи.
Древовидная структура, поля id и top отвечают за дерево, есть некое поле isgroup.
так вот, надо посчитать количество записей, у которых isgroup равно 3, начиная от указанного id вглубь дерева
маленький пример
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
id	name 		top	isgroup
------------------------------------
1	самосвалы		0	1
2	катки		0	1
3	большие		1	1
4	средние		1	1
5	малые		1	1
6	фото1		3	3
7	фото2		4	3
8	фото3		5	3
То есть, если применить эту функцию к самосвалам, вернуть надо 3 (3 фотки), если к большим, средним или малым, то 1.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35301506
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хорошо бы глубина груп была бы небольшая фиксированая.
Что-то типа:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select id, name, count( 1 ) cnt
from (
select id, name, t1.isgroup t1g, t2.isgroup t2g, t3.isgroup t3g, t4.isgroup t4g
from
tbl t1 left join tbl t2 on t1.id = t2.top
        left join tbl t3 on t2.id = t3.top
        left join tbl t4 on t3.id = t4.top ) x
where 
  (t1g= 3 ) or (t2g= 3 ) or (t3g= 3 ) or (t4g= 3 )  -- 3 in (t1g,t2g,t3g,t4g)
group by id  
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35301758
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не, каталог бесконечный ваще
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35301984
skol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
create function getPicturesCount(aID bigint) returns bigint
return (select sum(isgroup= 3 ) + sum(getPicturesCount(id)) from TABLE1 where top = aID);
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302057
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спасибо, но при попытке сделать
Код: plaintext
select getPicturesCount( 100695 );
выдало ошибку 1424: recursive stored function and triggers are not allowed.
может прав не хватает у юзера? или в функции дело?
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302129
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
хотя у себя из под рута выполнил, прав навалом, то же самое сказал
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302160
Фотография Nick Anikin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
рекурсивно процедуру нельзя вызывать в mysql, делайте через цикл
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302178
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
пожалуйста поясните, как, немного в мускуле понимаю
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302181
Фотография Nick Anikin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что как? цикл написать?
http://dev.mysql.com/doc/refman/5.0/en/while-statement.html
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302378
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
я думал эту функцию как то по другому запустить.
смысл писать тогда рекурсивные функции, если их нельзя запускать..
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302389
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nick Anikinрекурсивно процедуру нельзя вызывать в mysql, делайте через цикл
Можно
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302405
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xelaok Nick Anikinрекурсивно процедуру нельзя вызывать в mysql, делайте через цикл
Можно
помогите уже )))
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302424
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvov xelaok Nick Anikinрекурсивно процедуру нельзя вызывать в mysql, делайте через цикл
Можно
помогите уже )))
Через процедуру делай
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302459
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
CREATE FUNCTION `getPicturesCount`(aID bigint) RETURNS bigint( 20 )
return (select sum(isgroup= 3 ) + sum(getPicturesCount(id)) from foto_foto where top = aID);
function заменить на procedure?
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302555
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvov
Код: plaintext
1.
2.
CREATE FUNCTION `getPicturesCount`(aID bigint) RETURNS bigint( 20 )
return (select sum(isgroup= 3 ) + sum(getPicturesCount(id)) from foto_foto where top = aID);
function заменить на procedure?
хз, у меня тока так получилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
drop procedure if exists go;
drop function if exists calc;

delimiter |

create procedure go(p_id int, p_isgroup int, in k1 int, out k2 int)
begin
  declare done, l_id, l_isgroup int default  0 ;
  declare cur cursor for 
    select
      id,
      isgroup
    from
      foto_foto
    where
      top = p_id;
  declare continue handler for sqlstate '02000' set done =  1 ;

  set k2 = k1;
  open cur;
    repeat
      fetch cur into l_id, l_isgroup;
      if not done then
        call go(l_id, p_isgroup, k2 + if(l_isgroup = p_isgroup,  1 ,  0 ), k2);
      end if;
    until done end repeat;
  close cur;
end
|

create function calc(p_id int, p_isgroup int) returns int
begin
  declare k int default  0 ;
  call go(p_id, p_isgroup, k, k);
  return k;
end
Код: plaintext
select calc( 1 ,  3 )
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302628
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попрошу кинуть в меня камнем за этот вариант.
Перед тем как ловить камень поясню, рекурсия имеет обыкновение падать при определенном уровне вложенности, а этому абсолютно пофиг.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
delimiter //
create FUNCTION `selectSomething`(recPID INT, recType INT) RETURNS bigint( 20 )
BEGIN
  DECLARE ids BLOB;
  DECLARE tempIDScount INT;
  DECLARE IDScount INT;
  set tempIDScount =  0 ;
  select group_concat(t.id), count(t.id) into ids, IDScount 
	from temptab t 
	where t.top = recPID or t.id=recPID;

	WHILE tempIDScount < IDScount DO
  	set tempIDScount = IDScount;
    select 
			group_concat(t.id), count(t.id) into ids, IDScount
		from 
			temptab t
		where 
			FIND_IN_SET(t.id,ids)	>  0 
			OR FIND_IN_SET(t.top,ids) > 0 ;
  END WHILE;
  return (select count(*) from tempTab where
	FIND_IN_SET(ID,ids)	>  0  and isGroup=recType);						
	
END//
delimiter ;
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302734
Фотография Nick Anikin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAPA3OTПопрошу кинуть в меня камнем за этот вариант.зачем же камнем? я сразу написал - лучше через цикл переделать :)
MAPA3OTПеред тем как ловить камень поясню, рекурсия имеет обыкновение падать при определенном уровне вложенности, а этому абсолютно пофиг.в mysql даже специальный параметр есть - max_sp_recursion_depth
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302737
Фотография Nick Anikin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xelaok Nick Anikinрекурсивно процедуру нельзя вызывать в mysql, делайте через цикл
Можнода, я неправильно написал, имел ввиду функцию - как хотел автор
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302762
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вообщем скрипт Nick Anikin выдал что Recursive limit 0 (as set by max_sp_recursion_depth variable) was exceeded by routine go
max_sp_recursion_depth надо увеличить? как его указать явно?
Код: plaintext
set @max_sp_recursion_depth= 3000 ;
перед выполнением - не помогло
скрипт MAPA3OT'a на небольшой вложенности работает верно, а на большой - нет.
В архиве дамп базы.
Если считать фотки экскаваторов
Код: plaintext
select selectSomething( 100695 , 3 );
, то будет 13, это верно.
А если считать самосвалы
Код: plaintext
select selectSomething( 100693 , 3 );
, то будет 133, хотя на самом деле там 248.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302784
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nick Anikinв mysql даже специальный параметр есть - max_sp_recursion_depth
Все равно есть максимальное ограничение (255), после которого даже изменение этого параметра не спасет. Опять-таки, если нас устроит некое значение в пределах от 0 до 255, то мы ткнемся в некое подобие этого:
Код: plaintext
1.
2.
ERROR  1436  (HY000): Thread stack overrun:   180628  bytes used of a  262144  byte stack, and
 81920  bytes needed.  Use 'mysqld -O thread_stack=#' to specify a bigger stack.
И будем долго с бубном подбирать нужное значение, поэтому я подумал и послал к черту скорость ради спасения собственных нервов.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302796
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
даже твой скрипт работает быстрей чем та же рекурсия на пхп. еще бы верно посчитала
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302804
skol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MAPA3OTПопрошу кинуть в меня камнем за этот вариант.
Перед тем как ловить камень поясню, рекурсия имеет обыкновение падать при определенном уровне вложенности, а этому абсолютно пофиг.


Минус один - многократный фуллскан таблицы (по числу вложенных уровней), т.е. тормоза
...
как вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
delimiter //
create FUNCTION `selectSomething`(recPID INT, recType INT) RETURNS bigint( 20 )
BEGIN
  DECLARE ids BLOB;
  DECLARE result INT;
  DECLARE childs BLOB;
  DECLARE currentPID char;
  set ids = concat(recPID,',');
  set result =  0 ;
  while length(ids) do
    set currentPID = substring_index(ids,',', 1 );
    set ids = substring(ids,length(currentPID)+ 2 );
    select group_concat(t.id), sum(isGroup=recType) + result into childs, result
	from temptab t 
	where t.top = currentPID;
    if length(childs) >  0  then
      set ids = concat(ids,childs,',');
    end if;
  end while;
  return result;						
END//
delimiter ;
здесь у нас запросы в цикле будут индексированными (при наличии индекса на top), и для каждого ид будут выполнены 1 раз
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302848
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skol, повис мускуль, 99 процентов нагрузки на камень
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302899
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvov, индекс на top установи
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302912
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
дак поставил перед тем как выполнить
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35302923
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvov
Код: plaintext
set @max_sp_recursion_depth= 3000 ;

Так напиши:
Код: plaintext
set session max_sp_recursion_depth= 255 
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303012
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvovвообщем скрипт Nick Anikin выдал что Recursive limit 0 (as set by max_sp_recursion_depth variable) was exceeded by routine go
max_sp_recursion_depth надо увеличить? как его указать явно?
Код: plaintext
set @max_sp_recursion_depth= 3000 ;
перед выполнением - не помогло
скрипт MAPA3OT'a на небольшой вложенности работает верно, а на большой - нет.
В архиве дамп базы.
Если считать фотки экскаваторов
Код: plaintext
select selectSomething( 100695 , 3 );
, то будет 13, это верно.
А если считать самосвалы
Код: plaintext
select selectSomething( 100693 , 3 );
, то будет 133, хотя на самом деле там 248.

Ай-ай-ай, а врать не хорошо, что вернет этот запрос?
Код: plaintext
1.
2.
3.
4.
5.
6.
select * from foto_foto where
	 (top =  100693  and isgroup= 3 )
or (isgroup= 3  and top in (select id from foto_foto where top =  100693 ) )
or (isgroup= 3  and top in (select id from foto_foto where top in (select id from foto_foto where top =  100693 )) )
or (isgroup= 3  and top in (select id from foto_foto where top in (select id from foto_foto where top in (select id from foto_foto where top =  100693 ))) )
or (isgroup= 3  and top in (select id from foto_foto where top in (select id from foto_foto where top in (select id from foto_foto where top in (select id from foto_foto where top =  100693 )))) )
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303033
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAPA3OT djvov
Хотя, стоп, отставить, у вас точно такая функция?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
drop function if exists selectSomething;
delimiter //
create FUNCTION `selectSomething`(recPID INT, recType INT) RETURNS bigint( 20 )
BEGIN
	DECLARE ids BLOB;
  DECLARE tempIDScount INT;
  DECLARE IDScount INT;
  set tempIDScount =  0 ;
  set session group_concat_max_len =  3000000000 ;
	select group_concat(t.id), count(t.id) into ids, IDScount 
	from foto_foto t 
	where t.top = recPID or t.id=recPID;
	WHILE tempIDScount < IDScount DO
  	set tempIDScount = IDScount;
    select 
			group_concat(t.id), count(t.id) into ids, IDScount
		from 
			foto_foto t
		where 
			FIND_IN_SET(t.id,ids)	>  0 
			OR FIND_IN_SET(t.top,ids) > 0 ;
  END WHILE;
	return (select count(distinct id) from foto_foto where
	FIND_IN_SET(ID,ids)	>  0  and isGroup=recType);	
END//
delimiter ;
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303043
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skol[
Минус один - многократный фуллскан таблицы (по числу вложенных уровней), т.е. тормоза

Фулскан - действительно тормоз прогресса, но я пока не понимаю как без него ибо
ваша функция к сожалению сложится (должна сложиться) на больших объемах данных, substring при работе с blob - проще сразу повеситься.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303067
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MAPA3OT skol
Ну и еще один плевок в вас (я очень раздражительный перед похмельем), сравните:
допусти по всем уровням вложенности (пусть будет 10) всего 150 записей. а теперь сравните - полный перебор таблицы 10 раз со 150-ю быстрыми запросами.
Мне кажется, вы проигрываете в скорости.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303428
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мегазапрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
drop procedure if exists scan_proc;

delimiter |

create procedure scan_proc(p_id int, p_isgroup int, out cnt int)
begin
  set cnt =  0 ;
  set @ids = p_id;
  set @isgroup = p_isgroup;
  while not @ids is null do
     set @select_sql = concat(
        'select ',
        '  ( select count(*) from foto_foto where top in (', @ids, ') and isgroup = @isgroup ),',
        '  ( select group_concat(id) from foto_foto where top in (', @ids,') )',
        'into @k, @ids' 
      );  
     prepare scan_cnt from @select_sql;
     execute scan_cnt;
     set cnt = cnt + @k;
  end while;
  deallocate prepare scan_cnt;
end|
Код: plaintext
1.
call scan_proc( 100693 ,  3 , @a);
select @a;
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303440
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного оптимизировал:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
drop procedure if exists scan_proc;

delimiter |

create procedure scan_proc(p_id int, p_isgroup int, out cnt int)
begin
  set cnt =  0 , @ids = p_id;
  while not @ids is null do
     set @select_sql = concat(
        'select ',
        '  ( select count(*) from foto_foto where top in (', @ids, ') and isgroup = ', p_isgroup, ' ),',
        '  ( select group_concat(id) from foto_foto where top in (', @ids,') )',
        'into @k, @ids' 
      );  
     prepare scan_cnt from @select_sql;
     execute scan_cnt;
     set cnt = cnt + @k;
  end while;
  deallocate prepare scan_cnt;
end|
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303502
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати о пти4каx. Если каталог довол;но стабил;ний,
то можно полухеные зна4ения записать в новой колонке.
Ина4е рыскать каждый раз -- сервер загнется.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303657
skol_at_home
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MAPA3OT MAPA3OT skol
Ну и еще один плевок в вас (я очень раздражительный перед похмельем), сравните:
допусти по всем уровням вложенности (пусть будет 10) всего 150 записей. а теперь сравните - полный перебор таблицы 10 раз со 150-ю быстрыми запросами.
Мне кажется, вы проигрываете в скорости.
Зависит от размера таблицы, от количества уровней и от реализации FIND_IN_SET. Для небольшого количества уровней / небольшой таблицы ваш метод выгодней (я применяю близкий метод, но с клиента (пых))
Опять же, 150 быстрых запросов в хранимке это совсем не тоже самое, что 150 запросов с клиента.
Теперь последний камень ;-) - у вас постепенно набирается множество всех узлов со всех уровней, если же, как я упоминал, включить определение количества картинов в цикл, можно использовать множество только текущего уровня. Т.е. у вас в большинстве запросов часть возвращаемого результата дублирует то, что уже было известно.

про реализацию на пыхе: здесь все можно сделать гораздо оптимальней:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
function getAllChildsIds($parent) {
    $ids = array();
    $childs = array($parent)
    while(count($childs)) {
       $childs = explode(',',db_get_value("select group_concat(id) from table1 where top in (".implode(',',$childs).")");
       $ids = array_merge($ids,$childs);
    }
    return $ids;
}
Т.е. получаем те же 10 запросов (что гораздо более критично, так как они идут с клиента), но запросы будут использовать индекс, и не проводится лишняя работа, причем идеально добавить индекс не просто по top, а INDEX(top,id). В этом случае будет читаться только индекс.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303660
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skol_at_home
Сначала о грустном для меня, если честно, то сам предпочитаю искать с клиента, а не на сервере (фиг его знает, когда GROUP_CONCAT захлебнется, да и вообще сервак лишний раз мучать - бред)

Теперь о веселом. Самое забавное, что мой метод рулит именно на больших объемах данных, но с маленьким числом уровней, не смотря на то, что мы по n-раз возвращаем одно и тоже. По поводу substring - вы меня вряд ли сможете убедить, ну тормознутый он, что тут сделаешь. А реализация Filed_in_set меня вообще не волнует, это мусевская родная функция и как она работает - проблемы муси, а не мои.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303662
MAPA3OT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, а пока мы со skol пиписьками махались сзади тихо подошел xelaok и...

xelaok, я так с вами не играю это не честно и вообще это должен был написать я
А если честно, красиво, блин, и избегаем лишних проходов, и уменьшаем кол-во ненужной инфы, красиво.
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303710
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще немного посидел над запросом :)

Более быстрый вариант с правильным запросом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
drop procedure if exists scan_proc;

delimiter |

create procedure scan_proc(p_id int, p_isgroup int, out cnt int)
begin
  set cnt =  0 , @ids = p_id;
    while not @ids is null do
    set @select_sql = concat(
      'select group_concat(id), sum(isgroup = ', p_isgroup, ') '
      'from foto_foto ' 
      'where top in (', @ids,') '
      'into @ids, @k'
    );
    prepare scan_cnt from @select_sql;
    execute scan_cnt;
    set cnt = cnt + ifnull(@k,  0 );
  end while;
  deallocate prepare scan_cnt;
end

Такой же, но без prepare/execute:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
drop procedure if exists scan_proc2;

delimiter |

create procedure scan_proc2(p_id int, p_isgroup int, out cnt int)
begin
  declare ids blob default p_id;
  declare k int;

  set session group_concat_max_len =  256  *  1024 , cnt =  0 ;

  while not ids is null do
    select 
      group_concat(id),
      sum(isgroup = p_isgroup)
    from 
      foto_foto 
    where 
      find_in_set(top, ids) 
    into 
      ids, k;
			
    set cnt = cnt + ifnull(k,  0 );
  end while;
end
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303736
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xelaokЕще немного посидел над запросом :)
Более быстрый вариант с правильным запросом:


оба с одинаковой скоростью работают?)
последний вариант спас мой сайт))
спасибо вам всем огромное, и с праздником!!!
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303749
xelaok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
djvovоба с одинаковой скоростью работают?)
неа, второй, без prepare, в раза 4 медленее...
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303794
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
xelaok djvovоба с одинаковой скоростью работают?)
неа, второй, без prepare, в раза 4 медленее...
а как замеряли? с помощью пхп я представляю как замерить скорость.. а с помощью одного мускуля как?
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #35303872
djvov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
да, и правда, первый вариант быстрей, где то в 2-3 раза, говорит мой замер.
единственное, что у меня не получилось его из пхп выполнить, а второй вариант нормально работает.

Код: plaintext
1.
2.
3.
4.
5.
6.
function getfotocount($id)
{	
	mysql_query("call scan_proc($id,3,@a);");
	$rez=mysql_fetch_array(mysql_query("select @a;"));
	return $rez[0];
}

выдает пустую строку
но если из клиента выполнять, то все верно говорит.


Код: plaintext
1.
2.
3.
4.
5.
6.
function getfotocount($id)
{	
	mysql_query("call scan_proc2($id,3,@a);");
	$rez=mysql_fetch_array(mysql_query("select @a;"));
	return $rez[0];
}

выдает количество нормально
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
рекурсивная функция (процедура)
    #39085723
Poprygun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пример рекурсивного получения пути узла.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
DELIMITER $$

USE `itsd`$$

DROP PROCEDURE IF EXISTS `get_tree_path`$$

CREATE DEFINER=`root`@`%` PROCEDURE `get_tree_path`(_id INT, _path TEXT, _delimiter TEXT)
BEGIN
    DECLARE _parent_id INT ;
    DECLARE _nazvanie TEXT ;
    
	SET max_sp_recursion_depth = 10;
    SELECT 
        parent_id,
        nazvanie INTO _parent_id,
        _nazvanie 
    FROM
        tranzakciya_categoriya 
    WHERE id = _id ;
    IF (_path = '') 
    THEN SET _path = _nazvanie ;
    ELSE SET _path = CONCAT(_nazvanie, _delimiter, _path) ;
    END IF ;
    IF (_parent_id <> 0) 
    THEN CALL get_tree_path (_parent_id, _path, _delimiter) ;
    ELSE 
    SELECT 
        _path ;
    END IF ;
END$$

DELIMITER ;
...
Рейтинг: 0 / 0
рекурсивная функция (процедура)
    #39086651
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
43 сообщений из 43, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / рекурсивная функция (процедура)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]