Отключение ONLY_FULL_GROUP_BY это хорошая идея? - PullRequest
0 голосов
/ 24 января 2019

Я хочу получить клиентов, которые находятся в таблице «заказ», но не в таблице «клиент». «Быстрый заказ» клиентов. И я написал этот запрос:

SELECT `email`, `firstname` , `lastname`, `telephone`, `ip`, NULL
FROM `order`
WHERE `customer_id` = 0 AND `email` NOT IN (SELECT `email` FROM `ocustomer`)
GROUP BY `email`

Но я получаю:

Список SELECT содержит неагрегированный столбец (имя, фамилия, телефон, ip), это несовместимо с sql_mode = only_full_group_by

У меня есть два варианта:

  1. ВЫКЛЮЧЕНИЕ ONLY_FULL_GROUP_BY. Я знаю, как это сделать, но это хорошая идея? Я знаю, что это полезно, но в моем случае, если он включен, мне нужно переписать мой запрос
  2. Используя ANY_VALUE (), но он не работает с MariaDb. С другой стороны, я не могу использовать агрегатные функции, потому что у меня есть текстовые поля. Поэтому я понятия не имею, что еще нужно изменить, чтобы работать с ONLY_FULL_GROUP_BY.

Я запутался, что делать? Это хорошая идея, чтобы отключить ONLY_FULL_GROUP_BY или может быть есть другой способ переписать мой запрос без ANY_VALUE ()?

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Не используйте NOT IN ( SELECT ... ). Он работает плохо и не работает так, как вам нужно в этом случае. Используйте LEFT JOIN.

SELECT  DISTINCT
        o.`email`, o.`firstname`, o.`lastname`, o.`telephone`,
        o.`ip`, NULL
    FROM  `order` AS o
    LEFT JOIN  ocustomer AS oc USING(email)
    WHERE  o.`customer_id` = 0
      AND  oc.email IS NULL

Выгодно:

 order:     INDEX(customer_id)
 ocustomer: INDEX(email)

Это может быть даже лучше, тем более что оно «читается», как ваша формулировка проблемы:

SELECT  DISTINCT
        o.`email`, o.`firstname`, o.`lastname`, o.`telephone`,
        o.`ip`, NULL
    FROM  `order` AS o
    WHERE  o.`customer_id` = 0
      AND  NOT EXISTS( SELECT 1 FROM ocustomer WHERE email = o.email )

Используя DISTINCT вместо почти эквивалентного GROUP BY,

  • Избегает сообщения об ошибке.
  • Он покажет вам, связано ли это письмо с несколькими именами, телефонами и т. Д.

(Примечание. Вопреки распространенному мнению, SELECT DISTINCT(a), b ... не выглядит просто как "1023 *" как "отличающийся".)

0 голосов
/ 24 января 2019

Не стоит выключать его.Это поможет вам избежать ошибок, которые могут привести к неправильным результатам запроса.

Вы можете написать свой запрос следующим образом:

SELECT `email`, `firstname` , `lastname`, `telephone`, `ip`, NULL
FROM `order`
WHERE `customer_id` = 0 AND `email` NOT IN (SELECT `email` FROM `ocustomer`)
GROUP BY `email`, `firstname` , `lastname`, `telephone`, `ip`

Если у вас есть несколько строк на одно письмо с разными значениями, вывсе еще может использовать агрегатные функции.Не сумма или счет, а минимальная и максимальная работа.

SELECT `email`, MIN(`firstname`) AS firstname , MIN(`lastname`) AS lastname, /* ... you get the idea */
FROM `order`
WHERE `customer_id` = 0 AND `email` NOT IN (SELECT `email` FROM `ocustomer`)
GROUP BY `email`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...