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 шт):

Автор решения: Mike

Предлагаю до группировки уже заменить значения в колонках 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
→ Ссылка