Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 снова про деревья  [new]
непонимайу
Member

Откуда:
Сообщений: 177
--drop table test;

create table test
(id int,
 id_parent int ,
 name      varchar(50));

insert into test values(1, null, 'соки-воды');
insert into test values(2, 1, 'вода такая');
insert into test values(3, 1, 'вода сякая');
insert into test values(4, null, 'техника');
insert into test values(5, 4, 'цифровая');
insert into test values(6, 5, 'фотооаппарты');

select case  when id_parent is null then name
             else func(id_parent) end
from test;

надо получить такой результат:

соки-воды
соки-воды, вода такая
соки-воды, вода сякая
техника
техника, цифровая
техника, цифровая, фотооаппарты
не доходит, как переделать функцию выбора предков, для этого%)
ltree начал смотреть.
28 ноя 07, 14:18    [4975310]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
Oleg Bartunov
Member

Откуда:
Сообщений: 216
непонимайу
--drop table test;

create table test
(id int,
 id_parent int ,
 name      varchar(50));

insert into test values(1, null, 'соки-воды');
insert into test values(2, 1, 'вода такая');
insert into test values(3, 1, 'вода сякая');
insert into test values(4, null, 'техника');
insert into test values(5, 4, 'цифровая');
insert into test values(6, 5, 'фотооаппарты');

select case  when id_parent is null then name
             else func(id_parent) end
from test;

надо получить такой результат:

соки-воды
соки-воды, вода такая
соки-воды, вода сякая
техника
техника, цифровая
техника, цифровая, фотооаппарты
не доходит, как переделать функцию выбора предков, для этого%)
ltree начал смотреть.


смотри и тебе будет счастье.
28 ноя 07, 15:14    [4975890]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
Thamerlan
Member

Откуда: Рига
Сообщений: 203
Лучше посмотрите contrib tablefunc функцию connectby.
28 ноя 07, 15:15    [4975910]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
zuxul
Member

Откуда: Вологда
Сообщений: 54
Нет PostgreSQL, только Oracle, но думаю эквивалент nvl() в PostgreSQL точно есть
select 
       nvl(t2.name,t1.name) n2,
       case when t1.id_parent is not null 
            then
                t1.name 
            end n1
                from test t1
left join test t2
on t1.id_parent=t2.id
order by n2, n1 nulls first
29 ноя 07, 09:27    [4979037]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
непонимайу
Member

Откуда:
Сообщений: 177
Oleg Bartunov
смотри и тебе будет счастье.
посмотрел, не обрел). Вы соавтор ltree?
Thamerlan
Лучше посмотрите contrib tablefunc функцию connectby.
не непонял, как в branch вставить поле name, а id-ки через запятую не нужны
SELECT * FROM connectby('test', 'id', 'id_parent', '1', 0, ', ')
 AS t(keyid text, parent_keyid text, level int, branch  text);
"1";"" ;0; "1"
"2";"1";1;"1, 2"
"3";"1";1;"1, 3"
к тому мне нужна одна строка, а не набор.
zuxul
Нет PostgreSQL, только Oracle, но думаю эквивалент nvl() в PostgreSQL точно есть
на pg это будет так:
select 
       NULLIF(t2.name,t1.name) as n2,
       case when t1.id_parent is not null 
            then
                t1.name 
            end as n1
                from test t1
left join test t2
on t1.id_parent=t2.id
order by n2, n1 
но это не то, что надо

пошел изобретать велосипед...
29 ноя 07, 10:52    [4979724]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
zuxul
Member

Откуда: Вологда
Сообщений: 54
непонимайу
но это не то, что надо
Да, протупил - не заметил фотоаппараты :)
29 ноя 07, 11:26    [4980081]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
.:Ajvol:.
Member

Откуда: Москва
Сообщений: 9
непонимайу
на pg это будет так:
select 
       NULLIF(t2.name,t1.name) as n2,
       case when t1.id_parent is not null 
            then
                t1.name 
            end as n1
                from test t1
left join test t2
on t1.id_parent=t2.id
order by n2, n1 
но это не то, что надо



ISNULL - MSSQL (из двух значений выбирает то, которое NOT NULL)
NVL - ORACLE
IFNULL - MySQL
COALESCE - POSTGRESQL (выбирает первое NOT NULL из списка произвольной длины)

NULLIF - это обратная операция - выдаёт NULL, если первый аргумент равен второму
29 ноя 07, 11:30    [4980121]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
Золотая рыбка
Member

Откуда:
Сообщений: 115
А если так?
CREATE OR REPLACE FUNCTION "get_tree_values" (_id integer, out _name varchar) RETURNS varchar AS
$body$
DECLARE
    full_name varchar; 
    nm varchar;  
    _id_parent integer;
BEGIN
    SELECT id_parent, name INTO _id_parent,full_name FROM test WHERE id = _id;  
    IF (_id_parent IS NULL) THEN 
    	_name =  full_name;    
	  	RETURN;
    END IF; 

    SELECT get_tree_values(_id_parent) INTO nm;
     full_name = full_name || ', ' ||  nm; 
    _name =  full_name;
    RETURN;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

select id, get_tree_values(id) FROM test

Только в этом варианте в обратном порядке значения пойдут.
'Фотоаппараты, цифровая, техника'
29 ноя 07, 11:32    [4980135]     Ответить | Цитировать Сообщить модератору
 Re: снова про деревья  [new]
непонимайу
Member

Откуда:
Сообщений: 177
Золотая рыбка
А если так?
красиво. спасибо.
29 ноя 07, 12:07    [4980460]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить