Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите составить запрос. Деревья 
:(
    Опции темы
KEM
Дата 1.11.2007, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 152
Регистрация: 28.1.2005

Репутация: нет
Всего: 2



День добрый! Давно не брался уже за sql, но вот встала задача. Бьюсь над ней уже ужасно долго, и никак не получается, а оч. надо. 
И имеется таблица, с родительским отношением элементов. Нужно зная   parent_id ребёнка найти всех его родителей. 

+----+-----------+----------------+
| id   | parent_id | name         |
+----+-----------+----------------+
|  4   |         3   | name1          |
|  7   |         4   | name2          |
| 11  |         4   | name3          |
| 14  |        11  | name4          |
+----+-----------+----------------+

Например для name4, последовательность будет выглядеть так  name4 -> name3 -> name1.
Может есть у кого какие идеи ? Заранее благодарен.


Это сообщение отредактировал(а) KEM - 1.11.2007, 19:05
--------------------
Мы растворяем сознание жизни, реальностью стал бешеный ритм...
PM MAIL   Вверх
KEM
Дата 2.11.2007, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 152
Регистрация: 28.1.2005

Репутация: нет
Всего: 2



Вот навоял запросик который выводит 2-х родителей от из весного ребёнка, новот как его сделать универсальным ?  :wall: 
Код

SET @pr =884;# MySQL вернула пустой результат (т.е. ноль строк).
SELECT id, (
@pr := parent_id
) AS a, name
FROM `folders` 
WHERE (
id = @pr 
)
UNION 
SELECT id, (
@pr := parent_id
) AS a, name
FROM `folders` 
WHERE TYPE = 'd'
AND (
id = ( @pr ) 
)
 

Безусловно повторяя кусок 
Код

UNION 
SELECT id, (
@pr := parent_id
) AS a, name
FROM `folders` 
WHERE TYPE = 'd'
AND (
id = ( @pr ) 
)


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

Это сообщение отредактировал(а) KEM - 2.11.2007, 00:37
--------------------
Мы растворяем сознание жизни, реальностью стал бешеный ритм...
PM MAIL   Вверх
JustNick
Дата 2.11.2007, 04:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 28.11.2006

Репутация: нет
Всего: нет



Одним запросом не получается, а вот процедуру можно создать, только доделать нужно - с циклом какая-то беда, но что-то вроде такого:

DELIMITER $$

DROP PROCEDURE IF EXISTS `import_data`.`Path_Proc` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `Path_Proc`(i int, out @path varchar(150))
BEGIN

  set @isExist = true;
  SET @CurID = i;
  set @path = '';

  while @isExist and not @path is null do
    if exists(select * from `import_data`.`new table` where `id` = @curID and not `Parent_ID` is null and `parent_id` in (select `id` from `import_data`.`new table`)) > 0 then
      select @path = trim(cast(CONCAT_WS(' ',ifnull(@path,''),concat('->',`name`)) as char(150))) from `import_data`.`new table` where id = @CurID;
      select @CurID = `Parent_ID` from `import_data`.`new table` where `id` = @curID;
      set @isExist = true;
    else
      set @isExist = false;
    end if;
  end while;

  return @path;

END $$

DELIMITER ;
PM MAIL   Вверх
pompei
Дата 2.11.2007, 05:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.9.2007

Репутация: нет
Всего: 6



Нужно ещё учесть чтобы вот такие данные:

+-----+-----------+------+
| id  | parent_id | name |
+-----+-----------+------+
| 123 |       123 | name |
или
|   1 |         2 | name |
|   2 |         3 | name |
|   3 |         1 | name |
+-----+-----------+------+

Не приводили к зацикливанию

Не пойму зачем это делать с помощью SQL, можно на стороне приложения например так:
Код


sub getParentId {
  my $id = shift;
  my $dbh = getDBIConnection();
  my $sth = $dbh->prepare( "SELECT parent_id FROM folders WHERE id = ?" );
  my $rv = $sth->execute( $id );
  my ($parentId) = $rv->fetchrow_array();
  $dbh->disconnect();
  return $parentId;
}

sub getNameById {
  my $id = shift;
  my $dbh = getDBIConnection();
  my $sth = $dbh->prepare( "SELECT name FROM folders WHERE id = ?" );
  my $rv = $sth->execute( $id );
  my ($name) = $rv->fetchrow_array();
  $dbh->disconnect();
  return $name;
}

#Целевая функция
sub getParentPath {
  my $id = shift;
  my $ids = {};
  my $ret = [];
  while ($id) {
     if ($ids->{$id}) {
       die "Ошибка зацикливания";
     }
     $ids->{$id} = 1;
     unshift @$ret, getNameById( $id );
     $id = getParentId( $id );
  }
  return $ret;
}



Это сообщение отредактировал(а) pompei - 2.11.2007, 06:25
--------------------
А всё оказывается гораздо проще: пассивные наноструктуры - активные наноструктуры - системы наносистем - молекулярные наносистемы - сингулярность! По пять лет на каждый этап.
PM MAIL   Вверх
JustNick
Дата 2.11.2007, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 28.11.2006

Репутация: нет
Всего: нет



Цитата(pompei @ 2.11.2007,  05:49)
Не пойму зачем это делать с помощью SQL, можно на стороне приложения


 smile  
Это кому как нравится. Мне например больше по душе выполнение максимума на сервере, а клиент получает результат.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0577 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.