SQL-запрос для выбора пар значений в столбце 1, которые соответствуют одному из двух шаблонов в столбце 2

#sql #postgresql

#sql #postgresql

Вопрос:

Мои данные выглядят следующим образом:

 |User ID        |Install Version |
|--------------------------------|
|  Value A      |     Pattern 1  |
|  Value B      |     Pattern 1  |
|  Value A      |     Pattern 2  |
|  Value C      |     Pattern 2  |
|  Value D      |     Pattern 1  |
  

Я хочу выбрать только идентификаторы пользователей, в которых 1 или более записей совпадают Pattern 1 и Pattern 2 . Итак, в приведенном выше примере я бы хотел выбрать только Value a .

В принципе, я хочу сравнить, какие идентификаторы пользователей установили как «Lite», так и «Full» программного продукта. Например, поскольку Value B в нем нет записей, сопряженных с Pattern 1 И Pattern 2 , я не хочу его выбирать.

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

Ответ №1:

Я могу придумать два способа, один с помощью GROUP_CONCAT, а другой с помощью подзапроса.

 SELECT user_id, GROUP_CONCAT(installed_version) as all_patterns
FROM your_table
GROUP BY user_id
HAVING all_patterns REGEXP 'Pattern 1'
AND all_patterns REGEXP 'Pattern 2';
  

 SELECT * FROM 
(
SELECT user_id, installed_version FROM your_table
WHERE installed_version LIKE 'Pattern 1'
) as tmp
WHERE installed_version LIKE 'Pattern 2';
  

Комментарии:

1. Точно такие же у меня были ощущения, когда я нашел этот метод 🙂

2. @LaurenzAlbe . . . Второе просто не работает. Первый не работает в Postgres. Я понятия не имею, почему за это проголосовали бы, если только тег MySQL не был удален в какой-то момент.

3. Я согласен с первым методом — он отлично работает при применении к моим данным. Я никогда не знал о INTERSECT

Ответ №2:

Таблица четко не определена, но в принципе запрос может выглядеть примерно так:

 SELECT user_id
FROM installation
WHERE version = 'version 1'
INTERSECT
SELECT user_id
FROM installation
WHERE version = 'version 2';
  

Ответ №3:

В Postgres я бы выбрал:

 SELECT user_id
FROM t
GROUP BY user_id
HAVING COUNT(*) FILTER (WHERE installed_version = 'Pattern 1') > 0 AND
       COUNT(*) FILTER (WHERE installed_version = 'Pattern 2') > 0
  

Ответ №4:

Вы можете использовать intersect для получения данных, содержащих как шаблон 1, так и шаблон 2

 SELECT [User ID]
FROM Table
WHERE [Install Version]='Pattern 1'
INTERSECT
SELECT [User ID]
FROM Table
WHERE [Install Version]='Pattern 2';