Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите упростить запрос (LISTAGG) oracle11g / 4 сообщений из 4, страница 1 из 1
25.12.2017, 14:51
    #39575514
Aleksey31
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить запрос (LISTAGG) oracle11g
Всем привет! Помогите пожалуйста как можно упростить мой запрос.
Необходимо рассчитать индекс (таблицы и данные тестовые прилагаю).
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create table geo_tab (geo_id number, ind_position number);
create table camp_geo_tab (camp_id number, geo_id number);
insert into geo_tab values (1, 1);
insert into geo_tab values (2, 2);
insert into geo_tab values (3, 3);
insert into geo_tab values (4, 4);
insert into geo_tab values (5, 5);
insert into geo_tab values (6, 6);
insert into geo_tab values (7, 7);
insert into camp_geo_tab values (1111, 3);
insert into camp_geo_tab values (1111, 5);
insert into camp_geo_tab values (2222, 1);
insert into camp_geo_tab values (2222, 7);
insert into camp_geo_tab values (2222, 2);
insert into camp_geo_tab values (3333, 4);


Теперь собственно рассчитываю индекс из 7 цифр в соответствии с позицией, если присутствует то ставим 9 иначе 0.
Результат должен выглядеть так:
1 1111 0090900
2 2222 9900009
3 3333 0009000
Мое решение:
Код: plsql
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.
SELECT camp_id, LISTAGG (a) WITHIN GROUP (ORDER BY camp_id, n) as ind
FROM (SELECT camp_id, MAX(i) as a, n 
      FROM (SELECT camp_id, i, n 
            FROM (SELECT camp_id,
                         CASE WHEN ind_position = 7 THEN 9
                           ELSE 0
                         END as i,
                         7 as n 
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 6 THEN 9
                           ELSE 0
                         END,
                         6
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 5 THEN 9
                           ELSE 0
                         END,
                         5
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 4 THEN 9
                           ELSE 0
                         END,
                         4
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 3 THEN 9
                           ELSE 0
                         END,
                         3
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 2 THEN 9
                           ELSE 0
                         END,
                         2
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id 
                  UNION ALL
                  SELECT camp_id,
                         CASE WHEN ind_position = 1 THEN 9
                           ELSE 0
                         END,
                         1
                  FROM geo_tab ggi,
                       camp_geo_tab ctgg 
                  WHERE ctgg.geo_id = ggi.geo_id ) t
            ORDER BY 1, 3)
      GROUP BY camp_id, n) t
GROUP BY camp_id;
...
Рейтинг: 0 / 0
25.12.2017, 15:18
    #39575538
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить запрос (LISTAGG) oracle11g
RTFM Partitioned Outer Join (FAQ)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
col mask for a10
select camp_id, listagg(nvl2(camp_geo_tab.geo_id, 9, 0)) within group (order by geo_tab.geo_id) as mask
  from camp_geo_tab partition by (camp_id) 
    right outer join geo_tab on (geo_tab.geo_id = camp_geo_tab.geo_id)
  group by camp_id
;

   CAMP_ID MASK
---------- ----------
      1111 0090900
      2222 9900009
      3333 0009000

...
Рейтинг: 0 / 0
25.12.2017, 15:35
    #39575556
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить запрос (LISTAGG) oracle11g
А зачем тут LISTAGG?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select  camp_id,
        to_char(sum(9 * power(10,7 - ind_position)),'fm0000000')
  from  camp_geo_tab a,
        geo_tab b
  where b.geo_id = a.geo_id
  group by camp_id
  order by camp_id
/

   CAMP_ID TO_CHAR(
---------- --------
      1111 0090900
      2222 9900009
      3333 0009000

SQL>



SY.
...
Рейтинг: 0 / 0
25.12.2017, 15:40
    #39575558
Aleksey31
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить запрос (LISTAGG) oracle11g
Elic, SY, большое человеческое спасибо! LISTAGG необязателен, просто не придумал иного решения(
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите упростить запрос (LISTAGG) oracle11g / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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