У меня есть этот набор таблиц:
таблица пользователей:
id username
1 user
таблица групп:
id name
1 g1
2 g2
Таблица users_groups:
user_id group_id
1 1
1 2
и я хочу получить этот результат:
id username user_groups
1 user g1,g2
я обнаружил, что с помощью string_agg решит проблему, и это было сделано на консоли postgres, но когда я использовал тот же запрос на php, я получил это сообщение
SQLSTATE[HY000]: General error: 1 no such function: string_agg
вот мой запрос:
select users.id, users.username, string_agg(groups.name, ', ')
from users
inner join users_groups on users.id = users_groups.user_id
inner join groups on groups.id = users_groups.group_id
group by users.id
кстати я использую:
Помимо пропавших GROUP BY
на users.username
в запросе нет ничего плохого, поэтому проблема может быть на стороне PHP. Решение, которое может сработать, — это превратить ваш запрос в представление, а затем вызвать его из PHP:
CREATE VIEW users_with_groups AS
SELECT users.id, users.username, string_agg(groups.name, ', ') AS groups
FROM users
JOIN users_groups ON users.id = users_groups.user_id
JOIN groups ON groups.id = users_groups.group_id
GROUP BY users.id, users.username;
Ваш PHP-код теперь становится довольно простым DB::table('users_with_groups')->select
вместо сложного утверждения у вас сейчас. (Обратите внимание, что VIEW
в SQL это как «виртуальная» таблица, вы можете применять к ней все операции так же, как к обычной таблице.)
Этот подход в целом является хорошей идеей: у PostgreSQL есть много других возможностей для SELECT
заявления, чем то, что практически возможно с PHP (или любой другой платформой в этом отношении). И все ваши сложные запросы будут собраны в одном месте (база данных), что значительно упростит профилирование и обслуживание системы безопасности.
Других решений пока нет …