Я создал эти тестовые данные:
srh@srh@[local] =# select * from customer join customergroupjoins on customer.key = customergroupjoins.keycustomer join groups on groups.key = customergroupjoins.keygroup;
key | name | keycustomer | keygroup | key | name
-----+--------+-------------+----------+-----+---------
1 | fred | 1 | 1 | 1 | alpha
1 | fred | 1 | 2 | 2 | beta
1 | fred | 1 | 3 | 3 | gamma
2 | jim | 2 | 1 | 1 | alpha
2 | jim | 2 | 2 | 2 | beta
2 | jim | 2 | 4 | 4 | delta
2 | jim | 2 | 5 | 5 | epsilon
3 | shelia | 3 | 1 | 1 | alpha
3 | shelia | 3 | 3 | 3 | gamma
3 | shelia | 3 | 5 | 5 | epsilon
(10 rows)
Таким образом, "Фред" является единственным клиентом во всем (альфа, бета, гамма). Чтобы определить, что:
srh@srh@[local] =# select * from customer
where exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 1)
and exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 2)
and exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 3);
key | name
-----+------
1 | fred
(1 row)
Это один из подходов. (1,2,3) - ваши известные групповые ключи - это параметры в подзапросах. Кто-то уже упоминал, что вам вообще не нужно присоединяться к таблице групп.
Другой способ:
select customer.*
from customer
join customergroupjoins g1 on g1.keycustomer = customer.key
join customergroupjoins g2 on g2.keycustomer = customer.key
join customergroupjoins g3 on g3.keycustomer = customer.key
where g1.keygroup = 1 and g2.keygroup = 2 and g3.keygroup = 3
Общая проблема поиска пользователей во всех группах (g_1, g_2 .. g_N) немного сложнее. Указанные выше запросы объединяются в таблицу ссылок (customergroupjoins) N раз, поэтому это разные запросы в зависимости от количества групп, с которыми вы проверяете.
Один из подходов к , который заключается в создании временной таблицы для использования в качестве параметра запроса: таблица содержит список групп, которые должны быть у всех клиентов. Так, например, создайте временную таблицу с именем «ParamGroups» (или «#ParamGroups» на SQL Server, чтобы пометить ее как временную), заполните ее интересующими вас групповыми ключами и затем сделайте следующее:
select * from customer where key in (
select keycustomer
from customergroupjoins
join paramgroup on paramgroup.keygroup = customergroupjoins.keygroup
group by keycustomer
having count(*) = (select count(*) from paramgroup))
Также, как новичок, я настоятельно рекомендую вам ознакомиться с советами по соглашениям об именах для таблиц и столбцов базы данных. У всех разные идеи (и они могут зажечь священные войны), но выберите некоторые стандарты (если они вам не продиктованы) и придерживайтесь их. Например, вы назвали одну таблицу «customer» (единственное число) и одну таблицу «groups» (множественное число), что выглядит плохо. Более обычно использовать «id» вместо «key» и использовать его в качестве суффикса («customer_id» или «CustomerID»), а не префикса. Весь аргумент CamelCase против old_skool - это больше вопрос стиля, как и первичный ключ-это-просто-id-not-table_id.