Удалить дупс после нескольких соединений - PullRequest
0 голосов
/ 18 мая 2018

Существует несколько таблиц:

элементы → items_roles → роли

элементы → зоны → role_zones → роли

items: id, zone_id
items_roles: role_id, item_id
zones: id
roles_zones: role_id, zone_id
roles: id, role_type_id, 

Я пытаюсь добавить поля ролей к элементам, он должен принимать role_type и это значение из items_zones anf, если оно равно NULL, получить запасное значение из зоны элемента (role_zones).

Я создал этот запрос:

SELECT
    items.id,
    z_roles.role_type_id as z_role_type_id, z_roles.id as z_role_id,
    i_roles.role_type_id as i_role_type_id, i_roles.id as i_role_id
  FROM items

  LEFT JOIN zones as j_zones ON j_zones.id = items.zone_id
  LEFT JOIN roles_zones ON roles_zones.zone_id = j_zones.id
  LEFT JOIN roles as z_roles ON (z_roles.id = roles_zones.role_id)

  LEFT JOIN items_roles ON items_roles.item_id = items.id
  LEFT JOIN roles as i_roles ON items_roles.role_id = i_roles.id
  AND (z_roles.role_type_id = i_roles.role_type_id)

  WHERE items.id = 834

  ORDER BY i_roles.id;

В результате я вижуэто:

id  | z_role_type_id | z_role_id | i_role_type_id | i_role_id 
-----+----------------+-----------+----------------+-----------
 834 |              5 |       111 |              5 |        68
 834 |             11 |       120 |             11 |       120
 834 |              7 |        77 |                |          
 834 |             12 |        91 |                |          
 834 |              4 |        78 |                |          
 834 |              2 |         2 |                |          
 834 |              5 |       111 |                |          
 834 |              8 |        36 |                |          
 834 |              8 |        36 |                |          
 834 |             12 |        91 |                |          
 834 |              4 |        78 |                |          
 834 |              2 |         2 |                |          
 834 |             11 |       120 |                |          
 834 |              7 |        77 |                |          
(14 rows)

Есть 14 строк, и мне нужно только 7.

Например, две строки:

id  | z_role_type_id | z_role_id | i_role_type_id | i_role_id
834 |              5 |       111 |              5 |        68
834 |              5 |       111 |                |    

Я хочу удалить строки с пустыми i_role_type_id и i_role_id, если уже есть строка с этими значениями.

Требуемый вывод:

id  | z_role_type_id | z_role_id | i_role_type_id | i_role_id 
-----+----------------+-----------+----------------+-----------
 834 |              5 |       111 |              5 |        68
 834 |             11 |       120 |             11 |       120
 834 |              7 |        77 |                |          
 834 |             12 |        91 |                |          
 834 |              4 |        78 |                |          
 834 |              2 |         2 |                |         
 834 |              8 |        36 |                |          
(7 rows)

Как переписать запрос?

Теперь все работает:

SELECT items.id
  ,z_roles.role_type_id as z_role_type_id
  ,z_roles.id as z_role_id
  ,MAX(i_roles.role_type_id) as i_role_type_id
  ,MAX(i_roles.id) as i_role_id
FROM items

LEFT JOIN zones as j_zones ON j_zones.id = items.zone_id
LEFT JOIN roles_zones ON roles_zones.zone_id = j_zones.id
LEFT JOIN roles as z_roles ON (z_roles.id = roles_zones.role_id)

LEFT JOIN items_roles ON items_roles.item_id = items.id
LEFT JOIN roles as i_roles ON items_roles.role_id = i_roles.id
AND (z_roles.role_type_id = i_roles.role_type_id)

WHERE items.id = 834
Group By items.id, z_roles.role_type_id, z_roles.id
ORDER BY items.id, i_role_id;

Результат:

 id  | z_role_type_id | z_role_id | i_role_type_id | i_role_id 
-----+----------------+-----------+----------------+-----------
 834 |              5 |       111 |              5 |        68
 834 |             11 |       120 |             11 |       120
 834 |              7 |        77 |                |          
 834 |              2 |         2 |                |          
 834 |             12 |        91 |                |          
 834 |              4 |        78 |                |          
 834 |              8 |        36 |                |          
(7 rows)

1 Ответ

0 голосов
/ 18 мая 2018

Похоже, все, что вам нужно, это простая Group By в вашем операторе select для агрегирования данных.

Group By items.id, z_roles.role_type_id, z_roles.id

В частности;

 SELECT items.id
  ,z_roles.role_type_id as z_role_type_id
  ,z_roles.id as z_role_id
  ,MAX(i_roles.role_type_id) as i_role_type_id
  ,MAX(i_roles.id) as i_role_id
FROM items

LEFT JOIN zones as j_zones ON j_zones.id = items.zone_id
LEFT JOIN roles_zones ON roles_zones.zone_id = j_zones.id
LEFT JOIN roles as z_roles ON (z_roles.id = roles_zones.role_id)

LEFT JOIN items_roles ON items_roles.item_id = items.id
LEFT JOIN roles as i_roles ON items_roles.role_id = i_roles.id
AND (z_roles.role_type_id = i_roles.role_type_id)

WHERE items.id = 834
Group By items.id, z_roles.role_type_id, z_roles.id
ORDER BY i_roles.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...