Postgres 查询以查找联合中是否已存在组合 table
Postgres query to find if combination already exist in junction table
我有一个简单的聊天模块,允许帐户创建多用户房间。
给定以下架构 - 是否可以创建一个查询来检查给定用户的房间是否已经存在?
如果此检查可能导致性能问题 - 您能否提出其他设计或方法?
示例数据:
- chat_id: 1, users: [1, 2, 3]
- chat_id: 2, users: [2, 3]
- chat_id: 3, users: [1]
- chat_id: 4, users: [5, 6]
所需查询:
Check if chat room for users [2, 3] exists => true, id: 2
Check if chat room for users [1, 2, 3] exists => true, id: 1
Check if chat room for users [2, 6] exists => false
Check if chat room for users [1, 2, 6] exists => false
我正在使用 postgres 11.2
编辑:
如果给定的组合存在,我也应该能够获得聊天 ID。
我认为这符合您的要求:
select ca.chat_id
from chat_account ca
group by ca.chat_id
having count(*) filter (where account_id in (2, 3)) = 2 and
count(*) = 2;
您还可以使用:
having array_agg(account_id order by account_id) = array[2, 3]
你需要这样的东西
with selected_users as (select * from accounts where id in (2,3)),
users_chat_rooms as (
select chat_id,
array_agg(account_id order by account_id asc) users_in_room
from chat_account
group by chat_id
)
select * from users_chat_rooms
where chat_id in (select chat_id from chat_account where account_id in (select id from selected_users))
and users_in_room = (select array_agg(id order by id asc) from selected_users)
参见 fiddle https://dbfiddle.uk/?rdbms=postgres_11&fiddle=f360a05c57a33f5c130fcfa0d55429ff
您可能会向特定用户展示此内容,因此您可以过滤 "logged in" 用户的聊天记录。
select * from users_chat_rooms
where chat_id in (select chat_id from chat_account where account_id = <logged_in_user>)
and users_in_room = (select array_agg(id order by id asc) from selected_users)
根据其他答案,我最终编写了自己的查询:
SELECT chat_id FROM chat_account
WHERE chat_id IN (
SELECT c2.chat_id
FROM chat_account c2
WHERE c2.account_id IN (2, 3)
)
GROUP BY chat_account.chat_id
HAVING array_agg(chat_account.account_id) = ARRAY[2, 3]
我有一个简单的聊天模块,允许帐户创建多用户房间。
给定以下架构 - 是否可以创建一个查询来检查给定用户的房间是否已经存在?
如果此检查可能导致性能问题 - 您能否提出其他设计或方法?
示例数据:
- chat_id: 1, users: [1, 2, 3]
- chat_id: 2, users: [2, 3]
- chat_id: 3, users: [1]
- chat_id: 4, users: [5, 6]
所需查询:
Check if chat room for users [2, 3] exists => true, id: 2
Check if chat room for users [1, 2, 3] exists => true, id: 1
Check if chat room for users [2, 6] exists => false
Check if chat room for users [1, 2, 6] exists => false
我正在使用 postgres 11.2
编辑: 如果给定的组合存在,我也应该能够获得聊天 ID。
我认为这符合您的要求:
select ca.chat_id
from chat_account ca
group by ca.chat_id
having count(*) filter (where account_id in (2, 3)) = 2 and
count(*) = 2;
您还可以使用:
having array_agg(account_id order by account_id) = array[2, 3]
你需要这样的东西
with selected_users as (select * from accounts where id in (2,3)),
users_chat_rooms as (
select chat_id,
array_agg(account_id order by account_id asc) users_in_room
from chat_account
group by chat_id
)
select * from users_chat_rooms
where chat_id in (select chat_id from chat_account where account_id in (select id from selected_users))
and users_in_room = (select array_agg(id order by id asc) from selected_users)
参见 fiddle https://dbfiddle.uk/?rdbms=postgres_11&fiddle=f360a05c57a33f5c130fcfa0d55429ff
您可能会向特定用户展示此内容,因此您可以过滤 "logged in" 用户的聊天记录。
select * from users_chat_rooms
where chat_id in (select chat_id from chat_account where account_id = <logged_in_user>)
and users_in_room = (select array_agg(id order by id asc) from selected_users)
根据其他答案,我最终编写了自己的查询:
SELECT chat_id FROM chat_account
WHERE chat_id IN (
SELECT c2.chat_id
FROM chat_account c2
WHERE c2.account_id IN (2, 3)
)
GROUP BY chat_account.chat_id
HAVING array_agg(chat_account.account_id) = ARRAY[2, 3]