Поиск пользователей по крайней мере с одним элементом - PullRequest
0 голосов
/ 19 мая 2019

Например, у меня есть следующая таблица: Information

user_id | item
-------------------------
45      | camera
36      | smartphone
23      | camera
1       | glucose monitor
3       | smartwatch
2       | smartphone
7       | smartphone
2       | camera
2       | glucose monitor
2       | smartwatch

Как я могу проверить, какой user_id имеет хотя бы один из каждого элемента?

Следующие элементы не будут статичными и могут каждый раз отличаться.Однако в этом примере есть 4 уникальных элементов: camera, smartphone, smartwatch, glucose monitor

Ожидаемый результат:

Поскольку у user_id: 2 есть хотя бы один из каждого элемента, результат будет:

user_id 
2

Вот что я пытался сделать до сих пор, однако, если список элементов изменится с 4 уникальныхпредметы на 3 уникальных предмета, я не думаю, что это больше работает.

SELECT *
FROM Information
GROUP BY Information.user_id
having count(DISTINCT item) >= 4

Ответы [ 3 ]

3 голосов
/ 19 мая 2019

Один из подходов заключается в агрегировании по user_id, а затем в утверждении о том, что различное число item_id соответствует общему отличному количеству item_id из всей таблицы.

SELECT
    user_id
FROM Information
GROUP BY
    user_id
HAVING
    COUNT(DISTINCT item_id) = (SELECT COUNT(DISTINCT item_id) FROM Information);
1 голос
/ 19 мая 2019

Вы можете попробовать использовать self-join по количеству и общему количеству

SELECT t1.user_id
FROM (
  SELECT user_id,COUNT(DISTINCT item) cnt
  FROM T
  GROUP BY user_id
) t1 JOIN (SELECT COUNT(DISTINCT item) cnt FROM T) t2
WHERE t1.cnt = t2.cnt

или exists

Запрос 1 :

SELECT t1.user_id
FROM (
  SELECT user_id,COUNT(DISTINCT item) cnt
  FROM T
  GROUP BY user_id
) t1 
WHERE exists(
  SELECT 1
  FROM T tt
  HAVING COUNT(DISTINCT tt.item) = t1.cnt
)

Результаты

| user_id |
|---------|
|       2 |
0 голосов
/ 19 мая 2019

Еще один способ решения этой проблемы - использование CTE и функции density_rank.Это также дает лучшую производительность на MySQL.Функция Dense_Rank ранжирует каждый элемент среди пользователей.Я считаю количество отдельных предметов и говорю, выбираю пользователей, которые имеют максимальное количество разных предметов.

 With Main as (
   Select user_id
          ,item
          ,Dense_Rank () over (
              Partition by user_id
              Order by item
              ) as Dense_item
   From information
   )
 Select
     user_id
 From Main
 Where 
     Dense_item = (
        Select
           Count(Distinct item)
        from
           information);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...