2014-09-23 4 views
0

У меня есть пользователи таблицаРегистрация и многообразны и условие

ID  NAME 
1  John 
2  Mike 
3  Jack 

и таблица с атрибутами и идентификаторами пользователей

USER ATTRIBUTE 
1  1 
1  2 
2  4 

Мне нужно, чтобы выбрать все пользователь с атрибутом 1 и 2 (так, в этом примере пользователь № 1 Джон). Атрибуты могут быть более двух.

I'v пытался

SELECT * FROM user u LEFT JOIN attributes a ON u.id = a.user 
WHERE a.attribute = 1 AND a.attribute = 2 

, но, конечно, это не работает ..

ответ

2

Для этого вам потребуется использовать команду IN() и GROUP BY ... HAVING. Также нет необходимости в соединении, если все, что вам нужно, это идентификаторы пользователя. Так что-то вроде:

SELECT user, COUNT(attribute) AS attribute_count 
FROM attributes 
WHERE attribute IN(...) /* include your set of attributes here */ 
GROUP BY user 
HAVING attribute_count = ? /* include number equal to number of attribute ID's in IN() above */ 

Если вам нужен идентификатор пользователя и имена, которые вы можете просто присоединиться к этой записи набор, полученный из запроса выше в качестве фильтра в таблице пользователей:

SELECT user.id, user.name 
FROM user 
INNER JOIN 
    (
    SELECT user, COUNT(attribute) AS attribute_count 
    FROM attributes 
    WHERE attribute IN(...) /* include your set of attributes here */ 
    GROUP BY user 
    HAVING attribute_count = ? /* include number equal to number of attribute ID's in IN() above */ 
) AS filter 
    ON user.id = filter.user 
+0

Это большой запрос, а таблица пользователей - это «ядро». Что делать, если я уже использовал «наличие» в другом месте? (чтобы показать пользователям в X км от выбранной области) – poh

+0

@poh На самом деле, когда вы ввели свой комментарий, я показывал, как применить этот фильтр к основной таблице через соединение. –

+0

удивительный, он работает! – poh

0

, имеющий положение может быть использовано с суммой

SELECT u.id FROM user u 
INNER JOIN attributes a ON u.id = a.user 
group by u.id 
having (sum(case when attribute in (1,2) then 1 else 0 end)) =2 
0

Вы ищете для всех пользователей, для которых существует атрибут 1 и 2. Один из способов решения этого вопроса - как следует из названия - это пункт EXISTS:

select * 
from users u 
where exists 
(
    select * 
    from user_attributes ua 
    where ua.user = u.id 
    and ua.attribute = 1 
) 
and exists 
(
    select * 
    from user_attributes ua 
    where ua.user = u.id 
    and ua.attribute = 2 
); 

Другой способ: найти все идентификаторы пользователей, которые имеют оба атрибута, а затем выбрать из таблицы users.

select * 
from users 
where id in 
(
    select user 
    from user_attributes 
    where attribute in (1,2) 
    group by user 
    having count(*) = 2 
); 

В случае, если есть повторяющиеся записи в атрибутах, вы должны заменить count(*) с count(distinct attribute).

Есть и другие способы приблизиться к этому. Я думаю, что эти два упоминаются довольно прямолинейно.

0

Вам потребуется группа по .... с

SELECT u.name 
FROM 
    users u 
JOIN 
    attributes a 
    ON u.id = a.user 
WHERE a.id IN (1,2) 
GROUP BY u.name 
    HAVING COUNT(*) = 2 
Смежные вопросы