ОБНОВЛЕНИЕ: https://www.db -fiddle.com / f / 5fGUTSsAhGRPYPk33wDSzz / 0
Извините за вопрос, очень похожий на предыдущий, но яя действительно застрял здесь.
Есть несколько таблиц:
- items → items_roles → роли
- items → зоны → role_zones → role
Структура:
- items: id, zone_id
- items_roles: role_id, item_id
- zone: id
- role_zones: role_id, zone_id
- role: id, role_type_id,
Я пытаюсь добавить поля ролей к элементам, он должен принимать role_type, и это значение из items_zones, и если это NULL, получить запасное значение из зоны(role_zones).
Я начал с:
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_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 | | |
А теперь этот запрос:
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,
MAX(CASE
WHEN (i_roles.role_type_id = 5) THEN i_roles.id
WHEN (z_roles.role_type_id = 5) THEN z_roles.id
END) AS role_type_5_value,
MAX(CASE
WHEN (i_roles.role_type_id = 11) THEN i_roles.id
WHEN (z_roles.role_type_id = 11) THEN z_roles.id
END) AS role_type_11_value,
MAX(CASE
WHEN (i_roles.role_type_id = 7) THEN i_roles.id
WHEN (z_roles.role_type_id = 7) THEN z_roles.id
END) AS role_type_7_value
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 | role_type_5_value | role_type_11_value | role_type_7_value
-----+----------------+-----------+----------------+-----------+-------------------+--------------------+-------------------
834 | 5 | 111 | 5 | 68 | 111 | |
834 | 11 | 120 | 11 | 120 | | 120 |
834 | 7 | 77 | | | | | 77
834 | 2 | 2 | | | | |
834 | 12 | 91 | | | | |
834 | 4 | 78 | | | | |
834 | 8 | 36 | | | | |
(7 rows)
Несколько строк и неправильное значение для role_type_5_value
.Вероятно, из-за агрегатора MAX.Можно ли использовать что-то вроде first
агрегатора (потому что строки, упорядоченные по i_role_id и первые результаты верны)?
Я хочу это:
id | role_type_5_value | role_type_11_value | role_type_7_value
-----+-------------------+--------------------+-------------------
834 | 68 | 120 | 77
Я пытался group by
по агрегированным полям (role_type_5_value
, role_type_11_value
, role_type_7_value
), но это просто не работает.