Перестроение запроса

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
pH
Сообщения: 10
Зарегистрирован: 09 ноя 2005, 13:43

Перестроение запроса

Сообщение pH » 10 май 2006, 20:00

Добрый день .
Помогите пожалуйста разобратся с такой проблемой :
Есть простенький запрос

SELECT NAME_LAST , NAME_FIRST, NAME_MIDDLE
from Table
WHERE .....

Запрос возвращает не более 4-х записей . Вопрос следующий :
Каким образом результат
------------------------------------------------------
NAME_LAST | NAME_FIRST | NAME_MIDDLE |
------------------------------------------------------
Name_L_1 | Name_F_1 | Name_M_1 |
Name_L_2 | Name_F_2 | Name_M_2 |

Представить в виде ОДНОЙ строки такого типа :
Name_L_1 Name_F_1 Name_M_1 , Name_L_2 Name_F_2 Name_M_2

Заранее благодарен .

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 11 май 2006, 08:43

Пробежаться по выборке и сложить в кучу, перемежая запятыми.

aaa3d
Сообщения: 69
Зарегистрирован: 23 ноя 2005, 11:06

Сообщение aaa3d » 11 май 2006, 08:57

в хранимой процедуре примерно такое

output_string='';

for SELECT NAME_LAST , NAME_FIRST, NAME_MIDDLE
from Table
WHERE ..... into :l_name,:f_name, :m_name do
beign
if output_string<>'' then output_string=output_string||','
output_string=output_string||:l_name||:f_name||:m_name;
end
suspend;

pH
Сообщения: 10
Зарегистрирован: 09 ноя 2005, 13:43

Сообщение pH » 11 май 2006, 11:48

Вот код моей процедуры:

Код: Выделить всё

CREATE PROCEDURE PARENTS_STR (
    ID INTEGER)
RETURNS (
    OUTPUT_STRING VARCHAR(200))
AS
DECLARE VARIABLE NL VARCHAR(60);
DECLARE VARIABLE NF VARCHAR(30);
DECLARE VARIABLE NM VARCHAR(30);
BEGIN
OUTPUT_STRING='';
  FOR
    select p.Name_Last || ' ' as NL , p.name_first || ' ' as NF, p.name_middle || ' ' as NM
      from      PERSONS p
       left join relatives r on p.id=r.id_child
     WHERE p.ID in
       (SELECT ID_PARENT FROM relatives WHERE ID_CHILD=:ID )
    INTO :NL,
         :NF,
         :NM
  DO
  BEGIN
       OUTPUT_STRING = OUTPUT_STRING ||  :NL  || :NF ||  :NM ;
    SUSPEND;
  END
END
Но возвращает она все равно не одну строку :(
если запрос имеет
----------------------------------------------------
Name_Last | Name_First | Name_Middle |
----------------------------------------------------
Name_L_1 Name_F_1 Name_M_1
Name_L_2 Name_F_2 Name_M_2

То процедура возвращает
Name_L_1 Name_F_1 Name_M_1
Name_L_1 Name_F_1 Name_M_1 Name_L_2 Name_F_2 Name_M_2

А если в процедуре написать
OUTPUT_STRING || ', ' || :NL || (поставить через запятую, как советовал ув. Dimitry Sibiryakov то вываливается arithmetic exeption... )

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 11 май 2006, 13:46

Ну и как говорится: "найди три отличия от решения aaa3d и получи счастье".
Ты всерьез думаешь что вся суммарная строка всегда уложится в 200 символов?
Собственно, лично я бы это делал на клиенте. Там ограничения на длину строк помягче...

pH
Сообщения: 10
Зарегистрирован: 09 ноя 2005, 13:43

Сообщение pH » 11 май 2006, 13:55

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

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 11 май 2006, 14:24

не лечится.
какой, в дупу, отчет на основании СТРОКИ, в которой идет просто перечисление ФИО через запятую???

pH
Сообщения: 10
Зарегистрирован: 09 ноя 2005, 13:43

Сообщение pH » 11 май 2006, 14:29

Если почитать справку , то иногда помогает ... :oops:

Исключения при выполнении убираются путем присваивания CHARACTER SET переменным и результату , а если убрать suspend за рпеделы цикла то возвращатся будет именно ОДНА строка ...

Спасибо всем за ответы .
Отдельное спавибо Dimitry Sibiryakov за строку
найди три отличия от решения aaa3d и получи счастье
Иногда и такие напутствия помогают :)

Код: Выделить всё

CREATE PROCEDURE PARENTS_STR (
    ID INTEGER)
RETURNS (
    OUTPUT_STRING VARCHAR(500) CHARACTER SET win1251)
AS
DECLARE VARIABLE NL VARCHAR(60) CHARACTER SET WIN1251;
DECLARE VARIABLE NF VARCHAR(30) CHARACTER SET WIN1251;
DECLARE VARIABLE NM VARCHAR(30) CHARACTER SET WIN1251;
BEGIN
OUTPUT_STRING='';
  FOR
    select p.Name_Last as NL , p.name_first as NF, p.name_middle  as NM
      from      PERSONS p
       left join relatives r on p.id=r.id_child
     WHERE p.ID in
       (SELECT ID_PARENT FROM relatives WHERE ID_CHILD=:ID )
    INTO :NL,
         :NF,
         :NM
  DO
  BEGIN
    if (OUTPUT_STRING = '' ) then OUTPUT_STRING = :NL||' '|| :NF||' '||:NM;
  else OUTPUT_STRING = OUTPUT_STRING||',  '||:NL||' '||:NF||' '||:NM;
   END
  suspend;
END

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 11 май 2006, 16:52

пользуйтесь тегами, особенно code, ёксель-моксель...
Исключения при выполнении убираются путем присваивания CHARACTER SET переменным и результату
кстати, если они ТАК убираются, то видать база не в win1251 создана.

Ответить