当前位置: 代码迷 >> MySQL >> MySQL非标准SQL写法有关问题记录
  详细解决方案

MySQL非标准SQL写法有关问题记录

热度:337   发布时间:2016-05-05 16:22:06.0
MySQL非标准SQL写法问题记录
如下SQL:
SELECT  t.message_id,  t.product_id,  t.drug_code,  t.analysis_result_type,  t.analysis_type,  t.severity,  (    CASE      t.drug_code       WHEN '001'       THEN       (SELECT         sd.chineseProductName       FROM        `149wuhu_platform`.tb_product sd       WHERE sd.id = t.product_id)       ELSE b.drug_id     END  ) product_name,  IF(    b.source = '配伍禁忌'     AND b.message_id LIKE '10%',    t.message,    b.message  ) message,  SUM(COUNT) AS amount,  '1' AS dataType,  IFNULL(b.rule_type, 0) rule_type,  IFNULL(c.apply_status, 0) apply_status,  b.status_recipe alert_status FROM  opt_alertmessage_statistic AS t   INNER JOIN `149wuhu_platform`.tb_drug_rule_message b     ON t.message_id = b.message_id   LEFT JOIN `149wuhu_platform`.base_message_review c     ON c.message_id = t.message_id     AND c.apply_user_id = 1 WHERE t.key_date >= '2016-03-01'   AND t.key_date <= '2016-04-05'   AND (t.zone_id IN (2, 3, 4, 5, 6, 7, 8, 9)) GROUP BY t.message_id,t.product_id


上述执行结果总数是:2525行

但如果去掉最后面的:GROUP BY t.message_id,t.product_id 后执行结果却只有一条记录,这显然不符合正常逻辑(正常情况下查询结果是不低于2525行的),
造成此问题原因是上述SQL是非标准SQL,标准SQL要求中要求 SELECT后的查询字段必须和GROUP BY后的字段是相同的,即不能多也不能少!

备注:
1.在group by 里的列,可以直接出现在结果列(也可以少)。
2.不在group by 里的列,在经过聚合函数计算后可以出现在结果列(也可以多)。

PS:Oracle中是不支持此非标准写法的。

附加:
根据SQL92国际标准:
http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

If T is a grouped table, then each <column reference> in each <value
expression> that references a column of T shall reference a grouping
column or be specified within a <set function specification>.

简单的说,如果一个查询用了 group by,那么 select 可选择的 列 有两个可能 1. group by
中指定的列(或者其计算值),2. 聚合函数计算后的其它(非group by指定的)列。

而 MySQL 自作聪明(关闭ONLY_FULL_GROUP_BY),不符合国际标准,容忍了我们犯错,这也是引起我们自己混乱的原因。

举个例子:
gender age
男 11
女 22
男 33

这语句你们指望得到什么结果?
SELECT gender,age FROM USER GROUP BY gender

是:
男 11
女 22
还是:
女 22
男 33
这本来就不是个正确的SQL语句!
正确的语句应该改为这样:
SELECT gender,MIN(age) FROM USER GROUP BY gender

也就是将非group by的列放入某个聚合函数里。

建议以后写语句严格要求自己,不要让MySQL将我们带入歧途!
可能的话将ONLY_FULL_GROUP_BY打开。
  相关解决方案