1 Вопрос: Выберите все подписки, чьи пользователи не имеют других активных подписок

вопрос создан в Thu, May 2, 2019 12:00 AM

Я пишу запрос на очистку подписки, в котором должны быть выбраны все отмененные подписки, у которых у пользователей нет других активных подписок (приложение допускает несколько подписок на пользователя).

Я начал с этого:

SELECT * FROM subscriptions s WHERE status = 'canceled' AND (SELECT COUNT(*) FROM subscriptions s2 where s2.user_id = s.user_id AND status = 'active') = 0;

Однако я чувствую, что должен быть более простой /более простой /более производительный способ.

    
0
  1. "Однако я чувствую, что должен быть более простой /более простой /более производительный способ." Да, этот связанный подзапрос, скорее всего, лучше вместо этого записывается как объединение.
    2019-05-02 14: 51: 16Z
  2. Но смотрите Почему я должен предоставить MCVE для того, что мне кажется очень простым SQL-запросом? для предоставления примеров данных и ожидаемые результаты. Поскольку это вопрос производительности, этот вопрос также должен включать SHOW CREATE TABLE table для каждой таблицы, участвующей в вопросе, чтобы мы знали типы индексов и столбцов.
    2019-05-02 14: 51: 18Z
  3. @ Внутреннее объединение RaymondNijland здесь не будет работать ... вы ищете строки без соответствующей записи - для этого вам нужно внешнее соединение
    2019-05-02 14: 54: 34Z
  4. ага - видите, вы изменили внутреннее соединение для соединения - обычное соединение эквивалентно внутреннему соединению - поэтому внешнее все равно должно быть указано.
    2019-05-02 14: 56: 36Z
  5. я сказал "присоединиться" @FizzBuzz, но не говоря уже о Grammer, где здесь идет оффтоп, мы можем лучше удалить эти комментарии там, где мы это обсуждаем.
    2019-05-02 14: 59: 02Z
1 ответ                              1                         

NOT EXISTS может быть более интуитивно понятным:

SELECT * FROM subscriptions s WHERE status = 'canceled' 
AND NOT EXISTS 
(SELECT id FROM subscriptions s2 where s2.user_id = s.user_id AND status = 'active');

Вы также можете использовать левое соединение здесь:

SELECT * 
FROM 
subscriptions s LEFT OUTER JOIN
subscriptions s2 ON s.USER_ID = s2.USER_ID AND s2.status='active'
WHERE status = 'canceled' AND s2.id IS NULL 
    
3
2019-05-02 14: 51: 10Z
источник размещен Вот