Как найти результат с несколькими разными значениями в одном столбце? - PullRequest
0 голосов
/ 11 декабря 2018

Представьте, что у нас есть база данных с таблицей журналов и таблицей типов.Я хочу сделать запрос, чтобы выяснить, есть ли в UserX записи для определенных типов журналов.Допустим, что UserX зарегистрировал type_1 и type_2, но не type_3.Я хочу написать простой запрос, чтобы увидеть, является ли это истиной или ложью.

Сначала я попробовал что-то вроде:

SELECT * FROM logs AS l
INNER JOIN types AS t
ON t.id = l.type_id
WHERE t.name = "type_1"
AND t.name = "type_2"
AND t.name != "type_3";

Но я быстро понял, что это невозможно сделатькак это, так как t.name не может иметь несколько значений.Сейчас я попробовал несколько разных подходов, но, похоже, не могу найти подходящий для меня.Я уверен, что решение довольно простое, я просто не вижу его в данный момент.

Надеюсь, кто-то может указать мне правильное направление.

Я создал простую тестовую базу данных в этой скрипке, которую можно использовать для тестирования и примера: https://www.db -fiddle.com/ ж / nA6iKgCcJwKnXKsxaNvsLt / 0

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

Вы можете сделать это как Vamsi, но если вы предпочитаете более простой для понимания SQL, вы можете сделать это так:

SELECT * FROM logs AS l
INNER JOIN types AS t
ON t.id = l.type_id
WHERE true 
AND EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 1)
AND EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 2)
AND NOT EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 3)
0 голосов
/ 11 декабря 2018

Я не рекомендую использовать count(distinct) для этой цели.Это может быть дорого.Я бы просто сделал:

SELECT l.userId
FROM logs l INNER JOIN
     types t
     ON t.id = l.type_id
WHERE t.name IN ('type_1', 'type_2', 'type_3')
GROUP BY l.userId
HAVING SUM(t.name = 'type_1') > 0 AND  -- at least one
       SUM(t.name = 'type_2') > 0 AND  -- at least one
       SUM(t.name = 'type_3') = 0 ;    -- none
0 голосов
/ 11 декабря 2018

Один вариант с условным агрегированием.

SELECT l.userID
FROM logs AS l
JOIN types AS t ON t.id = l.type_id
GROUP BY l.userID
HAVING COUNT(DISTINCT CASE WHEN t.name IN ('type_1','type_2') THEN t.name END) = 2
AND COUNT(DISTINCT CASE WHEN t.name = 'type_3' THEN t.name END) = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...