两个应该等效的查询返回不同的结果

时间:2010-11-03 18:55:01

标签: mysql database sql

我有两个问题。第一个返回一些结果,第二个返回任何结果。他们在这里。

这个会返回一些结果:

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

我完全是竹子。有什么想法吗?

我的DBMS是MySQL。

1 个答案:

答案 0 :(得分:2)

第二个查询滥用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

由于WHEREGROUP 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条件。