powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запросы с переменным числом полей
8 сообщений из 8, страница 1 из 1
Запросы с переменным числом полей
    #32080182
Сергей_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В MS Access есть возможность создавать т.н. "перекрестные запросы", где число полей, также как и строк, зависит от содержания таблицы, т.е. значения какого-то поля выступают в роли имен полей выполненного запроса.
Например в результате выполнения запроса

TRANSFORM Max(prices.price) AS max_price
SELECT prices.year
FROM prices
GROUP BY prices.year
PIVOT prices.service;

получаем двухмерную таблицу, где по строкам будут года, по столбцам услуги а на пересечении соответствующие цены.

Подскажите пожалуйста, как подобное можно сделать в Oracle. Имеется ввиду именно представления данных в виде двухмерных таблиц, (т.е. расширения CUBE и ROLLUP не подходят, т.к. предоставляют только развертки).
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080188
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос - какая клиентская часть будет использоваться,
в принципе можно получать в списке выборки как-бы "переменное" количетво
"полей" если использовать cast(multiset()) преобразование.
Но к крос-таб репорту с access это никакого отношения не имеет.
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080198
Фотография MaxU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если заранее неизвестно к-во столбцов, то ИМХО надо динамически создавать запрос и выполнять его
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080208
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 MaxU
так мне представляется Сергей_ желает чтовы наименование колонок формировались из
ЗНАЧЕНИЯ поля(ей) таблицы.
Это правила крос-таб отчета.
Но одновременно с тем это есть полный нонсенс с точки зрания и реляционной алгебры и реляционных отношений и языка SQL
MS часто идет против стандартов - это уже как правило, не как исключение.

Поэтому как мне видится, динамический SQL в данном случае не поможет.
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080324
Фотография MaxU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ShgGena,

согласен!

я не знаю как это сделать в общем случае.

вот если число сервисов (prices.service) фиксировано, то это можно закодировать...
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080338
Фотография MaxU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"E pur si muove!" (и все таки она вертится!) (с) Джордано Бруно

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
set echo on

create or replace package my_pkg
as
    type refcursor is ref cursor;
    type array is table of varchar2( 30 );

    procedure pivot( p_max_cols       in number   default NULL,
                     p_max_cols_query in varchar2 default NULL,
                     p_query          in varchar2,
                     p_anchor         in array,
                     p_pivot          in array,
                     p_cursor in out refcursor );
end;
/

create or replace package body my_pkg
as

procedure pivot( p_max_cols          in number   default NULL,
                 p_max_cols_query in varchar2 default NULL,
                 p_query          in varchar2,
                 p_anchor         in array,
                 p_pivot          in array,
                 p_cursor in out refcursor )
as
    l_max_cols number;
    l_query    long;
    l_cnames   array;
begin
    -- figure out the number of columns we must support
    -- we either KNOW this or we have a query that can tell us
    if ( p_max_cols is not null )
    then
        l_max_cols := p_max_cols;
    elsif ( p_max_cols_query is not null )
    then
        execute immediate p_max_cols_query into l_max_cols;
    else
        raise_application_error(- 20001 , 'Cannot figure out max cols');
    end if;

    -- Now, construct the query that can answer the question for us...
    -- start with the C1, C2, ... CX columns:

    l_query := 'select ';
    for i in  1  .. p_anchor.count
    loop
        l_query := l_query || p_anchor(i) || ',';
    end loop;

    -- Now add in the C{x+1}... CN columns to be pivoted:
    -- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"

    for i in  1  .. l_max_cols
    loop
        for j in  1  .. p_pivot.count
        loop
            l_query := l_query ||
                'max(decode(rn,'||i||','||
                            p_pivot(j)||',null)) ' ||
                            p_pivot(j) || '_' || i || ',';
        end loop;
    end loop;

    -- Now just add in the original query
    l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';

    -- and then the group by columns...

    for i in  1  .. p_anchor.count
    loop
        l_query := l_query || p_anchor(i) || ',';
    end loop;
    l_query := rtrim(l_query,',');

    -- and return it
    execute immediate 'alter session set cursor_sharing=force';
    open p_cursor for l_query;
    execute immediate 'alter session set cursor_sharing=exact';
end;

end;
/

variable x refcursor
set autoprint on

begin
my_pkg.pivot
(p_max_cols_query => 'select max(count(*)) from emp 
                      group by deptno,job',
 p_query => 'select deptno, job, ename, sal, 
 row_number() over (partition by deptno, job
                    order by sal, ename)
 rn from emp a',
     
   p_anchor => my_pkg.array('DEPTNO','JOB'),
   p_pivot  => my_pkg.array('ENAME', 'SAL'),
   p_cursor => :x );
end;
/

begin
    my_pkg.pivot
    ( p_max_cols_query => 'select max(count(*)) from emp group by mgr',
      p_query => 'select a.ename mgr, b.ename, 
                         row_number() over ( partition by a.ename order by b.ename ) rn
                    from emp a, emp b
                   where a.empno = b.mgr',
      p_anchor => my_pkg.array( 'MGR' ),
      p_pivot  => my_pkg.array( 'ENAME' ),
      p_cursor => :x );
end;
/

begin
  my_pkg.pivot
  (p_max_cols =>  4 ,
   p_query => 'select job, count(*) cnt, deptno,
                  row_number() over (partition by job order by deptno) rn
                  from emp 
                  group by job, deptno',
   p_anchor => my_pkg.array('JOB'),
   p_pivot  => my_pkg.array('DEPTNO', 'CNT'),
   p_cursor => :x );
end;
/

"Expert one to one Oracle", page 579 (c) Tom Kyte
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080748
Alex_D
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Динамический SQL - тебя спасет )
Пример: Есть view test_view которая возвращает ....

Id_tovar, name_tovar, id_client, name_client, price

Необходим кростаб по вертикали клиенты
по горизонтали товары ....
на пересечении цена

Динамически формируем SQL

select name_client,
decode(id_tovar, 1, price, null) tovar_name -- где tovar_name - имя товара с ID = 1
decode(id_tovar, 2, price, null) tovar_name -- где tovar_name - имя товара с ID = 2
decode(id_tovar, 5, price, null) tovar_name -- где tovar_name - имя товара с ID = 5
...
decode(id_tovar, n, price, null) tovar_name -- где tovar_name - имя товара с ID = n
from test_view


На выходе кростаб ...
Я думаю, идея ясна ...)))))
...
Рейтинг: 0 / 0
Запросы с переменным числом полей
    #32080787
ShgGena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Alex
mogno sprosit a chto budet esli kolichestvo strok v table ... budet bolshe 1000?
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запросы с переменным числом полей
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]