Два запроса, которые должны быть эквивалентны, возвращают разные результаты - PullRequest
1 голос
/ 03 ноября 2010

У меня два запроса.Первый возвращает некоторые результаты, а второй ничего не возвращает.Вот они.

Этот возвращает несколько результатов:

select md5(concat(ad.line1, ad.line2, ad.city, s.name, ad.zip, group_concat(distinct c.name))) id,
       group_concat(distinct c.name) customer_names,
       count(distinct c.name) number_of_customers,
       ad.line1,
       ad.line2,
       ad.city,
       s.name state_name,
       ad.zip,
       a.import_id
  from address ad
  join account_address aa on aa.address_id = ad.id
  join account a on aa.account_id = a.id
  join import i on a.import_id = i.id
  join customer c on a.customer_id = c.id
  join state s on ad.state_id = s.id
 where a.import_id = 188
group by s.name, city, zip, line1, line2

Это ничего не возвращает:

select * from
(select md5(concat(ad.line1, ad.line2, ad.city, s.name, ad.zip, group_concat(distinct c.name))) id,
       group_concat(distinct c.name) customer_names,
       count(distinct c.name) number_of_customers,
       ad.line1,
       ad.line2,
       ad.city,
       s.name state_name,
       ad.zip,
       a.import_id
  from address ad
  join account_address aa on aa.address_id = ad.id
  join account a on aa.account_id = a.id
  join import i on a.import_id = i.id
  join customer c on a.customer_id = c.id
  join state s on ad.state_id = s.id
group by s.name, city, zip, line1, line2) v
where v.import_id = 188

Я полностью сбит с толку.Есть идеи?

Моя СУБД - MySQL.

1 Ответ

2 голосов
/ 03 ноября 2010

Второй запрос злоупотребляет MySQL расширением GROUP BY, которое позволяет выбирать неагрегированные столбцы.

import_id выбирается из случайной записи для группы во втором запросе, и не гарантируется, что это будет 188. Но запрос проверяет это после GROUP BY.

Пример данных:

grouper   value
1         1
1         1
1         2
1         3
2         1
2         2
2         3

Первый запрос:

SELECT  grouper, value
FROM    mytable
WHERE   value = 1

grouper   value
1         1
1         1
2         1

Поскольку WHERE выполняется до GROUP BY, этот запрос будет рассматривать только записи, содержащие value = 1 (которые были возвращены на предыдущем этапе):

SELECT   grouper, COUNT(*)
FROM     mytable
WHERE    value = 1
GROUP BY
         grouper

grouper   COUNT(*)
1         2
2         1

Второй запрос:

SELECT   grouper, COUNT(*), value
FROM     mytable
GROUP BY
         grouper

grouper   COUNT(*)  value
1         4         2
2         3         3

Поскольку value не группируется и не агрегируется, его можно взять из любой записи в группе! В этом случае это было взято из последних записей или соответствующих групп (но также может быть взято из любых других записей).

SELECT   *
FROM     (
         SELECT   grouper, COUNT(*), value
         FROM     mytable
         GROUP BY
                  grouper
         ) q
WHERE    value = 1

-- no rows

Поскольку на предыдущем этапе не было записи с value = 1 (так получилось, что значения были взяты из других записей), ни одна запись не удовлетворяет условию WHERE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...