Как объединить 3 таблицы в запросе postgresql с помощью postgresql join

#sql #postgresql #postgresql-9.6

Вопрос:

У меня есть 3 разных стола. Эти таблицы называются ro_master,tank_master,du_master.

Ниже приведены данные таблиц:

ro_master:

 id |  cms_code  |    ro_name    |      ro_address      
---- ------------ --------------- ----------------------    
  9 | 55381XA386 | RGE Name      | 89, Nilkamal Society    
  7 | 55381XA384 | Demo Name1    | 89, Nilkamal Society    
  5 | 55381XA381 | ABC Petroluem | Demo Address    
  6 | 55381XA383 | ABC Petroluem | Demo Address    
  8 | 55381XA385 | DEF Name      | 89, Nilkamal Society    
  4 | 55381XA382 | Demo Name     | Demo Address
 

tank_master:

 id | product | cms_code_id 
---- --------- -------------
 12 | HSD     |           4    
 13 | HSD     |           4    
 11 | MS      |           4    
 15 | HSD     |           7    
 16 | HSD     |           7    
 17 | MS      |           7    
 14 | MS      |           7    
 18 | XP      |           4    
 19 | HSD     |           4    
 20 | MS      |           9    
 21 | HSD     |           9
 

du_master:

 id | du_make | du_type | cms_code_id 
---- --------- --------- -------------
  6 | Midco   | Dual    |           7    
  7 | GVR     | MPD     |           7    
  8 | GVR     | MPD     |           7    
  9 | GVR     | MPD     |           7    
 10 | Midco   | Dual    |           4    
 11 | GVR     | MPD     |           4    
 12 | GVR     | QPD     |           4    
 13 | Midco   | Dual    |           4    
 14 | Midco   | QPD     |           7    
 15 | Midco   | QPD     |           7    
 16 | Midco   | Dual    |           9    
 17 | Midco   | MPD     |           9    
 18 | Midco   | Dual    |           9
 

Теперь я хочу присоединиться ко всем трем столам. используя определенные идентификаторы ro_master(например, идентификатор: 4,7).

Я использовал приведенный ниже запрос:

 SELECT rm.cms_code,rm.ro_name,rm.ro_address,
    tm.product,dm.du_type
FROM ro_master rm left JOIN
     tank_master tm
     ON rm.id = tm.cms_code_id left join du_master dm
     ON rm.id = dm.cms_code_id
WHERE rm.id in (4,7);
 

Результат, который я получил:

 cms_code  |  ro_name   |      ro_address      | product | du_type 
------------ ------------ ---------------------- --------- ---------    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | Dual    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | Dual    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | MS      | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | Dual    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | Dual    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | MPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | QPD    
 55381XA384 | Demo Name1 | 89, Nilkamal Society | HSD     | QPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual    
 55381XA382 | Demo Name  | Demo Address         | HSD     | MPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | QPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual    
 55381XA382 | Demo Name  | Demo Address         | XP      | Dual    
 55381XA382 | Demo Name  | Demo Address         | XP      | MPD    
 55381XA382 | Demo Name  | Demo Address         | XP      | QPD    
 55381XA382 | Demo Name  | Demo Address         | XP      | Dual    
 55381XA382 | Demo Name  | Demo Address         | MS      | Dual    
 55381XA382 | Demo Name  | Demo Address         | MS      | MPD    
 55381XA382 | Demo Name  | Demo Address         | MS      | QPD    
 55381XA382 | Demo Name  | Demo Address         | MS      | Dual    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual    
 55381XA382 | Demo Name  | Demo Address         | HSD     | MPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | QPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual    
 55381XA382 | Demo Name  | Demo Address         | HSD     | MPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | QPD    
 55381XA382 | Demo Name  | Demo Address         | HSD     | Dual
 

результат, который мне нужен, такой:
1

Комментарии:

1. Я вижу только проблему с форматированием (не повторяющиеся значения, которые одинаковы в предыдущей строке). чем проблема не должна решаться в postgresql,

2. Почему бы просто не объединить последние три столбца в массивы?

3. Для id=7 у вас есть 4 строки в одной объединенной таблице и 6 строк в другой. Как вы хотите, чтобы в результате было всего 5 строк? пожалуйста, объясните.

4. @Serg да, это 6 строк, по ошибке я добавляю только 5 строк

Ответ №1:

Предполагая tank_master , что и du_master должны быть соединены позиционно при сортировке по id

 SELECT rm.cms_code,rm.ro_name,rm.ro_address,
    tdm.product, tdm.du_type
FROM ro_master rm 
LEFT JOIN (
     SELECT coalesce(dm.cms_code_id, tm.cms_code_id) cms_code_id,
           tm.product, dm.du_type  
     FROM (
        select *,
           row_number() over(partition by cms_code_id order by id) rn 
        from tank_master) tm
     FULL JOIN(
        select *,
           row_number() over(partition by cms_code_id order by id) rn 
        from du_master) dm  
      ON dm.cms_code_id = tm.cms_code_id AND tm.rn = dm.rn
  ) tdm ON rm.id = tdm.cms_code_id 
WHERE rm.id in (4,7);