Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ SQL. Базы данных. _ FireBird: как преобразовать строки в столбцы?

Автор: Litkevich Yuriy 18.12.2008, 15:44

Никак не дается мне одна задачка, может кто-нибудь направит на путь истинный (хотябы даже мысли в слух).

Дано:
Хранимая Процедура (ХП) выбора FooProc(id INTEGER)
возвращает набор данных (N строк) из одного столбца для заданного id

Value
-------
value1
value2
...
valueN


Задача:
Сделать ХП MyProc(A INTEGER, B INTEGER) возвращаеющую набор данных (M строк) из N столбцов (по числу строк первой) плюс id в диаппазоне от A до B
т.е.:
ID    | Value1 | Value2 |... | ValueN
------------------------------------------
A     |value1  |value2  |... | valueN
A+1   |value1  |value2  |... | valueN
...
B     |value1  |value2  |... | valueN


где N - фиксированное целое число


----
FireBird 2.0

Автор: Tonal 19.12.2008, 15:01

В Firebird процедура должна возвращать фиксированное количество столбцов.
На версии 2.1
Можно извернутся с помощью EXECUTE STAIMENT + EXECUTE BLOCK + GTT но мне кажется это ужасный изврат.

Не проще ли выдернуть все данные на клиента и там извращаться?

П.С. В MS SQL & ORACL есть специальная конструкция PIVOT. Я не в курсе насчёт её стандартности.

Автор: Litkevich Yuriy 19.12.2008, 17:26

Цитата(Tonal @ 19.12.2008, 18:01) *
Не проще ли выдернуть все данные на клиента и там извращаться?
да вот на клиенте хотелось простоты, QSqlQueryModel + QTableView

Сделал посредством двух процедур. Одна делает из столбца строку, а вторая делает нужное кол-во строк.
вот так работает первая:
    FOR select
         Sum(case when p.TID = '0' then p.PWR end),
         Sum(case when p.TID = '1' then p.PWR end),
         Sum(case when p.TID = '2' then p.PWR end),
         Sum(case when p.TID = '3' then p.PWR end),
         Sum(case when p.TID = '4' then p.PWR end),
         Sum(case when p.TID = '5' then p.PWR end),
         Sum(case when p.TID = '6' then p.PWR end),
         Sum(case when p.TID = '7' then p.PWR end),
         Sum(case when p.TID = '8' then p.PWR end),
         Sum(case when p.TID = '9' then p.PWR end),
         Sum(case when p.TID = '10' then p.PWR end),
         Sum(case when p.TID = '11' then p.PWR end),
         Sum(case when p.TID = '12' then p.PWR end),
         Sum(case when p.TID = '13' then p.PWR end),
         Sum(case when p.TID = '14' then p.PWR end),
         Sum(case when p.TID = '15' then p.PWR end),
         Sum(case when p.TID = '16' then p.PWR end),
         Sum(case when p.TID = '17' then p.PWR end),
         Sum(case when p.TID = '18' then p.PWR end),
         Sum(case when p.TID = '19' then p.PWR end),
         Sum(case when p.TID = '20' then p.PWR end),
         Sum(case when p.TID = '21' then p.PWR end),
         Sum(case when p.TID = '22' then p.PWR end),
         Sum(case when p.TID = '23' then p.PWR end)
    from P_HOURLYPWR(:pointid, :indate) p
    INTO :f00, :f01, :f02, :f03, :f04, :f05, :f06, :f07, :f08, :f09, :f10, :f11, :f12, :f13, :f14, :f15, :f16, :f17, :f18, :f19, :f20, :f21, :f22, :f23
...


если не писать Sum то исходная таблица (содержащая один столбец) превращается в диагональную матрицу, в которой по диагонали размещаются значения исходной. Ну а с помощью Sum(case...) получаем строку из N столбцов.

Автор: kuler 22.12.2008, 11:27

да вы батенька, извращенец!

Автор: Litkevich Yuriy 22.12.2008, 14:53

kuler, а на более умную фразу знаний наскребешь?

Автор: kuler 22.12.2008, 16:21

ну а если бы там было не 23 а 1023?

Автор: Litkevich Yuriy 22.12.2008, 16:49

Цитата(kuler @ 22.12.2008, 19:21) *
ну а если бы там было не 23 а 1023?
а я везучий ;)

А у тебя варианты есть?

Автор: kuler 22.12.2008, 18:31

возвращать
A
val1
...
valn
A+1
val1
...
valn
...

преобразование на стороне клиента будет простейшим

короче врядли sql предназначен для вывода большого множества столбцов а уж тем более переменного, это использование не по назначению. СУБД это не оперативная память где как хочешь измерения фигаришь

Автор: AD 22.12.2008, 18:41

Цитата(kuler)
преобразование на стороне клиента будет простейшим

короче врядли sql предназначен для вывода большого множества столбцов а уж тем более переменного, это использование не по назначению. СУБД это не оперативная память где как хочешь измерения фигаришь

Покажи, пожалуйста, это преобразование на стороне клиента! Самому интересно увидеть решение! :) Буду благодарен, если откликнешься и напишешь код преобразования! :)

Автор: kuler 22.12.2008, 18:51

Цитата(AD @ 22.12.2008, 18:41) *
Покажи, пожалуйста, это преобразование на стороне клиента! Самому интересно увидеть решение! :) Буду благодарен, если откликнешься и напишешь код преобразования!

ну дык смотря какое нада, в данном случае я так понимаю надо будет из одного столбца расфасовать по нескольким столбцам? а конкретно во что пихать то нада?

Автор: AD 22.12.2008, 18:56

Цитата(kuler @ 22.12.2008, 18:51) *
ну дык смотря какое нада, в данном случае я так понимаю надо будет из одного столбца расфасовать по нескольким столбцам? а конкретно во что пихать то нада?

Задача не моя - не знаю. Но вот "простейший" код преобразования хочу видеть! Думаю занимать он будет строк 50 минимум! :) Возможно, даже больше.

Автор: kuler 23.12.2008, 11:10

Цитата(AD @ 22.12.2008, 18:56) *
Думаю занимать он будет строк 50 минимум! :) Возможно, даже больше.

ну и что? да и не факт, да и лучше вообще по уму когда данные из БД сливаются в объекты классов (ну к примеру объект "работник" и тд), ибо обычно визуальные интерфейсы не такие уж и банальные, да и задел на будущее

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)