Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Прошу помощи в решении задачи / 16 сообщений из 16, страница 1 из 1
09.08.2020, 11:25
    #39987897
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
День добрый. Новичок в SQL, спецы прошу Вашей помощи.

Есть задача:
Имею две таблицы (создавал временные, для ускорения выборок). В первой таблице создал поле, в которое нужно заносить данные из другой таблицы по некоторому условию. Одной записи из первой таблице может соответствовать несколько значений из второй, в этом случае нужно просто дописать в поле через разделитель ; это значение.

Пока начал с такого кода:

DECLARE
p4 VARCHAR2(2000);
BEGIN
FOR j IN
(
select * from XXT.XXT_PZV_321108_2018to2020_v1 pzv)
loop
BEGIN
p4:='';
FOR i IN
(
select * from XXT.XXT_EDV_321108_2017to2020_v1 edv
where 1=1
and (
lower (j.receiver_name) = lower (edv.payer_name)
or lower (j.receiver_name) = lower(edv.tir2)
or lower(j.receiver_name) = lower (substr (
edv.payer_name,
instr(edv.payer_name, '//',1,1)+2,
instr(edv.payer_name, '//',1,2)-3
))
)
and edv.r_date<j.r_date
and edv.a2>=j.amount
)
LOOP
--дописываем значение в поле

END LOOP;

END;
end loop;
END;
...
Рейтинг: 0 / 0
09.08.2020, 11:27
    #39987898
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
как дописывать значения в ячейку тоже пока не понимаю, первый раз вышел за рамки обычного select-а
...
Рейтинг: 0 / 0
09.08.2020, 11:29
    #39987899
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
Может плохо описал задачу, пока начал читать про курсоры и циклы...
...
Рейтинг: 0 / 0
09.08.2020, 12:30
    #39987908
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
На каком-нибудь паскале это сделать легко, через массив. А вот sql для меня пока загадка
...
Рейтинг: 0 / 0
09.08.2020, 14:13
    #39987920
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
Понял что на данном этапе задача для меня будет тяжеловата.

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

магазин | товар
---------------------------------
1-й_магазин | товар_1
1-й_магазин | товар_2
1-й_магазин | товар_3
1-й_магазин | товар_4
2-й_магазин | товар_5
3-й_магазин | товар_6
3-й_магазин | товар_7
3-й_магазин | товар_8
3-й_магазин | товар_9
3-й_магазин | товар_10
3-й_магазин | товар_11
4-й_магазин | товар_12
4-й_магазин | товар_13
5-й_магазин | товар_14

Как средствами sql привести ее к виду:

магазин | товары

1-й_магазин | товар_1; товар_2; товар_3; товар_4;
2-й_магазин | товар_5;
3-й_магазин | товар_6; товар_7; товар_8; товар_9; товар_10; товар_11;
4-й_магазин | товар_12; товар_13;
5-й_магазин | товар_14
...
Рейтинг: 0 / 0
09.08.2020, 14:15
    #39987921
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
pavelbp
Одной записи из первой таблице может соответствовать несколько значений из второй, в этом случае нужно просто дописать в поле через разделитель ; это значение
На каком-нибудь паскале это сделать легко, через массив. А вот sql для меня пока загадка


LISTAGG и все это можно сделать одним UPDATE.

SY.
...
Рейтинг: 0 / 0
09.08.2020, 14:19
    #39987922
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
Новичку нужно двигаться последовательно, от простого к сложному.
Начните с какого-нибудь учебника.

Код: 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.
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.
SQL> create table personal(id number, name varchar2(100), val varchar2(1000));

Table created


SQL> insert into personal(id, name) values (1, 'Иванов');

1 row inserted


SQL> insert into personal(id, name) values (2, 'Петров');

1 row inserted


SQL> insert into personal(id, name) values (3, 'Сидоров');

1 row inserted


SQL> create table log1(id number, id_personal varchar2(100), val number);

Table created


SQL> insert into log1 values (1, 1, 5);

1 row inserted


SQL> insert into log1 values (2, 1, 4);

1 row inserted


SQL> insert into log1 values (3, 2, 3);

1 row inserted


SQL> insert into log1 values (4, 2, 2);

1 row inserted


SQL> insert into log1 values (5, 2, 4);

1 row inserted


SQL> commit;

SQL> select * from personal;

        ID NAME                                                                             VAL
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Иванов                                                                           
         2 Петров                                                                           
         3 Сидоров  

SQL> 
SQL> declare
  2    vvv varchar2(1000);
  3  begin
  4    for c in (select id from personal) loop
  5      select listagg(val, ',') within group (order by id_personal) into vvv from log1 where id_personal = c.id;
  6      update personal set val = vvv where id = c.id;
  7    end loop;
  8  end;
  9  /

PL/SQL procedure successfully completed


SQL> select * from personal;

        ID NAME                                                                             VAL
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Иванов                                                                           4,5
         2 Петров                                                                           2,3,4
         3 Сидоров                                                                          

SQL> update personal set val = null;

3 rows updated


SQL> select * from personal;

        ID NAME                                                                             VAL
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Иванов                                                                           
         2 Петров                                                                           
         3 Сидоров           

SQL> update personal set val = (select listagg(val, ',') within group (order by id_personal) from log1 where id_personal = personal.id group by id_personal);

3 rows updated


SQL> select * from personal;

        ID NAME                                                                             VAL
---------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Иванов                                                                           4,5
         2 Петров                                                                           2,3,4
         3 Сидоров                                                                          

SQL> commit;


...
Рейтинг: 0 / 0
09.08.2020, 14:24
    #39987923
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
pavelbp,

Tы пытаешься денормализовать данные испоганив relational design. И что будет если сессия A удалит товар_1 из 1-й_магазин а в тоже время сессия Б добавит товар_5 в 1-й_магазин? Придется сериализовать транзакции и соответственно прощай производительнось.

SY.
...
Рейтинг: 0 / 0
09.08.2020, 14:43
    #39987932
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
SY,

не совсем наверное правильно написал,

магазин | товар
---------------------------------
1-й_магазин | товар_1
1-й_магазин | товар_2
1-й_магазин | товар_3
1-й_магазин | товар_4
2-й_магазин | товар_5
3-й_магазин | товар_6
3-й_магазин | товар_7
3-й_магазин | товар_8
3-й_магазин | товар_9
3-й_магазин | товар_10
3-й_магазин | товар_11
4-й_магазин | товар_12
4-й_магазин | товар_13
5-й_магазин | товар_14

это выборка (select из двух таблиц), хочу выборку привести к такому виду:

магазин | товары

1-й_магазин | товар_1; товар_2; товар_3; товар_4;
2-й_магазин | товар_5;
3-й_магазин | товар_6; товар_7; товар_8; товар_9; товар_10; товар_11;
4-й_магазин | товар_12; товар_13;
5-й_магазин | товар_14
...
Рейтинг: 0 / 0
09.08.2020, 14:46
    #39987933
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
dmdmdm,

Спасибо, за хороший пример! сейчас поковыряю еще в эту сторону.
...
Рейтинг: 0 / 0
09.08.2020, 14:47
    #39987934
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
pavelbp,

Так я уже намeкал GROUPB BY магазин + LISTAGG товар.

SY.
...
Рейтинг: 0 / 0
09.08.2020, 15:04
    #39987938
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
dmdmdm,

А теперь:

Session 1:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SQL> -- Session 1
SQL> delete log1 where id_personal = 2 and val = 3;

1 row deleted.

SQL> update personal set val = (select listagg(val, ',') within group (order by id_personal) from log1 where id_personal = personal.id group by id_personal);

3 rows updated.

SQL>



Session 2:

Код: plsql
1.
2.
3.
4.
5.
6.
SQL> -- Session 2
SQL> insert into log1 values (6, 2, 1);

1 row created.

SQL> update personal set val = (select listagg(val, ',') within group (order by id_personal) from log1 where id_personal = personal.id group by id_personal);



Session 2 висит. Sessiuon 1:

Код: plsql
1.
2.
3.
4.
5.
SQL> commit;

Commit complete.

SQL>



Session 2 закончила UPDATE. Session 2:

Код: plsql
1.
2.
3.
4.
5.
SQL> commit;

Commit complete.

SQL>



Смотрим:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> select * from personal;

        ID NAME       VAL
---------- ---------- ------------------------------
         1 Ivanov     4,5
         2 Petrov     1,2,3,4
         3 Sidorov

SQL>



SY.
...
Рейтинг: 0 / 0
09.08.2020, 15:18
    #39987942
pavelbp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
Задача еще немного усложнилась:

магазин | товар | цвет
---------------------------------
1-й_магазин | товар_1 | синий
1-й_магазин | товар_2 | красный
1-й_магазин | товар_3 | желтый
1-й_магазин | товар_4 | синий
2-й_магазин | товар_5 | оражевый
3-й_магазин | товар_6 | красный
3-й_магазин | товар_7 | красный
3-й_магазин | товар_8 | желтый
3-й_магазин | товар_9 | желтый
3-й_магазин | товар_10 | зеленый
3-й_магазин | товар_11 | зеленый
4-й_магазин | товар_12 | оражевый
4-й_магазин | товар_13 | синий
5-й_магазин | товар_14 | зеленый

это выборка (select из двух таблиц), нужно привести ее к такому виду:

магазин | товары

1-й_магазин | товар_1 цвет синий; товар_2 цвет красный; товар_3 цвет желтый; товар_4 цвет синий;
2-й_магазин | товар_5 цвет оражевый;
3-й_магазин | товар_6 цвет красный; товар_7 цвет красный; товар_8 цвет желтый; товар_9 цвет желтый; товар_10 цвет зеленый; товар_11 цвет зеленый;
4-й_магазин | товар_12 цвет оражевый; товар_13 цвет синий;
5-й_магазин | товар_14 цвет зеленый;

есть функция которая еще и столбцы объединяет как строковые переменные?
...
Рейтинг: 0 / 0
09.08.2020, 15:35
    #39987945
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
pavelbpесть функция которая еще и столбцы объединяет как строковые переменные?

Конкатеняция. Это не функция, это оператор.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
09.08.2020, 15:36
    #39987946
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
pavelbp

есть функция которая еще и столбцы объединяет как строковые переменные?


val1 || val2
...
Рейтинг: 0 / 0
09.08.2020, 22:11
    #39987993
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу помощи в решении задачи
dmdmdm
pavelbp

есть функция которая еще и столбцы объединяет как строковые переменные?


val1 || val2
даже функция есть
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions026.htm

только неудобная, принимает всего два параметра, на переменное количество не сподобились
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Прошу помощи в решении задачи / 16 сообщений из 16, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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