Union по двум полям нескольких таблиц, с выводом остальных полей
Есть таблицы с одинаковым полями следующего типа:
name: table_1
_________________________________________
|pole_1 | pole_2 | pole_3 | pole_4 |
-----------------------------------------
| 1 | 1 | 1 | 1 | - уникальная запись
| 2 | 2 | 2 | 2 | - уникальная запись
| 3 | 3 | 3 | 3 | - уникальная запись
-----------------------------------------
name: table_2
_________________________________________
|pole_1 | pole_2 | pole_3 | pole_4 |
-----------------------------------------
| 1 | 1 | 1 | 1 | - запись уже есть в table_1
| 1 | 2 | 3 | 4 | - уникальная запись
----------------------------------------
name: table_3
_________________________________________
|pole_1 | pole_2 | pole_3 | pole_4 |
-----------------------------------------
| 2 | 2 | 2 | 2 | - запись уже есть в table_1
| 3 | 4 | 5 | 6 | - уникальная запись
-----------------------------------------
....
name: table_10
_________________________________________
|pole_1 | pole_2 | pole_3 | pole_4 |
-----------------------------------------
| 3 | 4 | 5 | 6 | - запись уже есть в table_3
| 7 | 8 | 10 | 12 | - уникальная запись
----------------------------------------
Нужно сделать вывод всех уникальных записей, со всеми полями, со всех таблиц по двум полям, в порядке table_1, table_2, table_3,..,table_10.
Делаю следующие:
select pole_1, pole_2 from ( -- c GROUP BY могу указать только 2 поля, а нужно на вывод все 4 (pole_1, pole_2, pole_3, pole_4)
select * from (
select t.*, 1 as table_number from table_1 t
union all
select t.*, 2 as table_number from table_2 t
union all
select t.*, 3 as table_number from table_3 t
union all
....
union all
select t.*, 10 as table_number from table_10 t
) order by table_number
) group by pole_1, pole_2
Получаю записи, которые мне и нужны, но как теперь вывести оставшиеся поля (pole_3, pole_4), чтобы в результате получить таблицу исходного вида:
name: result_table (Таблица которая должна быть на выходе)
_________________________________________
|pole_1 | pole_2 | pole_3 | pole_4 |
-----------------------------------------
| 1 | 1 | 1 | 1 | - Запись взята именно из table_1
| 2 | 2 | 2 | 2 | - Запись взята именно из table_1
| 3 | 3 | 3 | 3 | - Запись взята именно из table_1
| 1 | 2 | 3 | 4 | - Запись взята именно из table_2
| 3 | 4 | 5 | 6 | - Запись взята именно из table_3
| 7 | 8 | 10 | 12 | - Запись взята именно из table_10
-----------------------------------------
Таблицы имеют приоритет по мере убывания, т.е. самый высокий приоритет у таблицы table_1, из которой нужна брать записи в первую очередь. Самый низкий приоритет у table_10, записи из неё берутся в последнюю очередь, если в других таблицах одинаковых записей обнаружено не было.
ВАЖНО: Поля не используемые в group by могут отличаться, поэтому и необходим приоритет.
Ответы (1 шт):
Предлагаю до группировки уже заменить значения в колонках pole_3 и pole_4 на требуемое. Первое, при сортировке по table_number и группировке по pole_1, pole2. А после этого уже сгруппируем по всем полям, что бы убрать дубликаты строк. Замену значений будем производить оконной функцией first_value:
select pole_1, pole_2, pole_3, pole_4
from (select pole_1, pole_2,
first_value(pole_3) over(partition by pole_1, pole_2 order by table_number) pole_3,
first_value(pole_3) over(partition by pole_1, pole_2 order by table_number) pole_4
from (
select t.*, 1 as table_number from table_1 t
union all
select t.*, 2 as table_number from table_2 t
union all
select t.*, 3 as table_number from table_3 t
union all
....
union all
select t.*, 10 as table_number from table_10 t
)
)
group by pole_1, pole_2, pole_3, pole_4
Второй вариант - пронумеровать строки в пределах будущей группы и взять первые:
select pole_1, pole_2, pole_3, pole_4
from (select pole_1, pole_2, pole_3, pole_4
row_number() over(partition by pole_1, pole_2 order by table_number) RN
from (
select t.*, 1 as table_number from table_1 t
union all
....
)
)
where RN=1