Как я уже писал, запросом сделать нельзя, по крайней мере я не могу придумать такого способа, если кто-то знает, то пусть поделится.
Я приведу пример для Oracle, для остальных БД синтаксис может сильно отличаться.
1) Допустим у нас есть две таблицы:
Сводная таблица - t_sv, в полях которой будут аккумулироваться сводные данные
Код:
create table t_sv(
p_sv_id number,
p_sv1 varchar2(100), -- в это поле будем заносить сводные данные из одной таблицы
p_sv2 varchar2(100) -- сюда из второй таблицы (ну, и дальше, если таблиц много)
);
Таблица из которой будем собирать данные (будем называть ее таблицей данных):
Код:
create table t1(
p_id number,
p_t1 varchar2(100) -- в этом поле будут данные, которые надо собрать в одну строку сводной таблицы, соответственно их id
);
2) Дальше, для примера, заполню пару строк в таблице данных:
Код:
insert into t1 values(1, 'A');
insert into t1 values(1, 'B');
insert into t1 values(1, 'C');
insert into t1 values(1, 'D');
insert into t1 values(2, 'AA');
insert into t1 values(2, 'BB');
insert into t1 values(2, 'CC');
commit;
3) Теперь создаю процедуру, которая будет склеивать множество строк из таблицы данных в одно поле сводной таблицы:
Код:
create or replace procedure test is
v_cur sys_refcursor;
v_str varchar2(100) := '';
v_rec t1%rowtype;
v_id number := -1;
begin
-- Создаю курсор для построчной обработки данных из таблицы данных
open v_cur for select t.p_id, t.p_t1
from t1 t
order by t.p_id;
-- цикл по всем записям таблицы данных
loop
-- извлекаю одну строку в переменную-запись
fetch v_cur into v_rec;
exit when v_cur%notfound;
-- есть ли в сводной таблице запись с p_id, который мы только что извлекли из таблицы данных
-- если ее нет, то получим 0 и избежим исключения NO_DATA_FOUND
select count(1) into v_id
from t_sv t
where t.p_sv_id=v_rec.p_id;
-- либо создаем новую запись в сводной таблице,
-- либо добавляем в уже существующую значение, извлеченное из таблицы данных
if v_id=0 then
insert into t_sv (p_sv_id, p_sv1) values (v_rec.p_id, v_rec.p_t1);
else
select t.p_sv1 into v_str
from t_sv t
where t.p_sv_id=v_rec.p_id;
v_str := v_str || ', ' || v_rec.p_t1;
update t_sv t
set t.p_sv1=v_str
where t.p_sv_id=v_rec.p_id;
end if;
end loop;
-- закрываю курсор
close v_cur;
end test;
4) Из жгучего любопытства запускаю процедуру:
И смотрю что получилось:
Код:
select * from t_sv;
P_SV_ID P_SV1
1 A, B, C, D
2 AA, BB, CC
Ну, и наконец, выводы. Если, не дай Бог, база данных построена так, что приходиться делать то, что было проделано выше, то стоит задуматься о том, как переделать структуру хранения данных, чтобы с ней стало возможно работать...