Подзапрос возвращает другой результат, чем при вызове сам по себе - PullRequest
1 голос
/ 20 мая 2019

Использование GROUP BY в подзапросе MySQL возвращает результаты, не появляющиеся при самостоятельном вызове запроса GROUP BY.

Этот пример настолько урезан, насколько я могу это сделать.

Iсоздается впечатление, что я упускаю что-то элементарное в использовании GROUP BY в подзапросе, но не нашел существующего вопроса или учебника, который решает эту конкретную проблему.

Сначала создайте таблицу:

CREATE TABLE Person (
    Id INT
    Email VARCHAR(20)
    );

INSERT INTO Person VALUES (1, "a@b.com");
INSERT INTO Person VALUES (2, "c@d.com");
INSERT INTO Person VALUES (3, "a@b.com");
INSERT INTO Person VALUES (5, "c@d.com");
INSERT INTO Person VALUES (7, "e@f.com");
INSERT INTO Person VALUES (11, "e@f.com");
INSERT INTO Person VALUES (13, "g@h.com");

Теперь сравните эти две пары запросов:

Тест 1: подзапрос с использованием явных идентификаторов

SELECT Id FROM Person WHERE Id IN (1, 2, 7, 13)

возвращает Id (1, 2, 7, 13)

SELECT Id FROM Person WHERE Id IN (SELECT Id FROM Person WHERE Id IN (1, 2, 7, 13))

возвращает Id (1, 2, 7, 13)

Тест 2: подзапрос с использованием GROUP BY для уникальности электронной почты (отдается первым в каждой группе)

SELECT Id FROM Person GROUP BY Email

возвращает Id (1, 2, 7, 13)

SELECT Id FROM Person WHERE Id IN (SELECT Id FROM Person GROUP BY Email)

возвращает Id (1, 2, 3, 5, 7, 11, 13) ... не (1, 2, 7, 13), как ожидалось.

Я ожидал, что выходные данные составного запроса в обоих этих тестах будут равны Id (1, 2, 7, 13), поскольку подзапрос в каждом выводит Id (1, 2, 7, 13) в качестве входных данных дляверхний левel query.

Это наводит меня на мысль, что отображаемые результаты на самом деле не являются полными (по крайней мере, когда речь идет о GROUP BY).Любое разъяснение этой запутанной ситуации будет с благодарностью.

Ответы [ 2 ]

1 голос
/ 20 мая 2019
 SELECT Id FROM Person GROUP BY Email

Этот запрос недопустим согласно стандарту SQL.Вы группируете по Email.Таким образом, вы получаете одну строку результатов на Email.Затем вы хотите показать идентификатор для Email.Но не существует ID на Email, их может быть много.Например, для Email = 'a@b.com' есть идентификаторы 1 и 3. СУБД должна выдавать ошибку.Но MySQL молча заменяет это на

 SELECT ANY_VALUE(Id) FROM Person GROUP BY Email

, то есть возвращает произвольно выбранное значение.Остается на всякий случай, вернет ли запрос ID 1 или 3 для Email = 'a@b.com'.

Это объясняет, почему вы получаете разные результаты.Один раз СУБД выбирает это значение один раз, другой.

0 голосов
/ 20 мая 2019

Group BY следует использовать с функцией агрегирования.

(Если вам нужен отличный результат, используйте предложение DISTINCT и не используйте group by неправильно)

В mysql versone <5.7 the ИспользованиеФункция группировки по группам без агрегации приводит к непредсказуемому результату. </p>

в mysql> = 5.7 по умолчанию не допускается, и этот тип использования приводит к ошибке.

Если вы хотите контролировать результат на основе группировки поВы должны использовать правильную функцию агрегирования, например: min () или max ()

    SELECT Id 
    FROM Person 
    WHERE Id IN ( SELECT min(Id )
        FROM Person 
        GROUP BY Email
      )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...