`

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打开。

MySQL查询原理及其慢查询优化案例
分享到:
评论

相关推荐

    mysql_学习笔记_02

    ` 这一行似乎包含了一些非标准字符,正确的写法应为 `CREATE DATABASE db_name;`。 **使用数据库** 一旦创建了数据库,接下来就需要使用这个数据库来执行进一步的操作,例如创建表、插入数据等。 **语法格式:** `...

    jdbc数据库连接写法

    使用ODBC连接数据库通常用于非标准的数据库类型或当没有可用的JDBC驱动时。 **代码示例:** ```java // 加载ODBC驱动 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // 连接数据库 Connection ...

    2009达内SQL学习笔记

    spool oracleday01.txt :开始记录 spool off :开始保存细节 四、SELECT语句:选择操作、投影操作。 select:从一个或多个表中检索一个或多个数据列。包含信息:想选择什么表,从什么地方选择。必须要有From...

    轻量级的c++封装

    1. **连接管理**:MySQL++提供了`sql::Connection`类,用于建立和管理与MySQL服务器的连接。通过构造函数,我们可以设置服务器地址、用户名、密码等参数,实现快速连接。 2. **查询执行**:`sql::Statement`类允许...

    sql语句中单引号嵌套问题(一定要避免直接嵌套)

    在大多数SQL方言中,包括MySQL、SQL Server、Oracle等,如果你的字符串内容里有一个单引号,你需要在它前面再添加一个单引号来进行转义。例如,如果你要搜索包含“标准间”的ROOMTYPE,正确的写法应该是: ```sql @...

    MySQL数据库开发规范

    - 整型字段根据业务需求选择合适的类型,并采用标准写法。 - 字符串类型使用`varchar`时必须指定长度,且长度通常不大于实际需求的两倍。 - 避免使用`char(m)`字符串类型。 - 默认情况下,不添加预留字段。 - 关联表...

    java开发中常用数据库JDBC连接写法.docx

    Java开发中的JDBC(Java Database Connectivity)是一种标准的API,允许Java程序与各种数据库进行交互。JDBC提供了统一的接口,使得开发者无需关心底层数据库的差异,只需编写相对通用的代码即可实现对不同数据库的...

    Mysql 数据库更新错误的解决方法

    当你去掉单引号后,语句意外地成功了,这是因为MySQL默认情况下允许在没有引号的情况下直接比较非数字字段,但这并不推荐,因为它可能导致解析歧义或安全问题。 至于图形界面生成的代码: ```sql UPDATE `web`.`...

    浅析一个MYSQL语法(在查询中使用count)的兼容性问题

    从MySQL 5.7版本开始,服务器执行更严格的SQL模式,按照标准SQL规定,如果在`SELECT`列表中包含了非聚合函数(如`id`, `name`),而没有`GROUP BY`子句,那么除了`COUNT(*)`之外的所有聚合函数都必须与`GROUP BY`中...

    数据库访问异步检测

    1. **数据库**:数据库是一种存储和管理数据的系统,如MySQL、Oracle、SQL Server、MongoDB等,它们允许开发者以结构化方式存取和处理数据。 2. **ADO(ActiveX Data Objects)**:ADO是Microsoft提供的一个组件,...

    2021-2022计算机二级等级考试试题及答案No.5283.docx

    12. 良好的编程实践:在设计程序时,应遵循使程序结构易于理解的原则,以提高代码的可读性和维护性,而非追求代码长度或限制特定语句的使用。 13. 主键的错误叙述:主键不能有重复值,不能为 NULL,且一个表可以有...

    2021-2022计算机二级等级考试试题及答案No.507.docx

    10. SQL语句用来添加职工号字段的有效性规则是ALTER TABLE语句,正确的写法是`ALTER TABLE 教师 ALTER 职工号 SET CHECK LEFT(职工号,3)="110"`。 11. 菜单后面的快捷键组合,如Ctrl+P,可以直接按下组合键执行相应...

    2021-2022计算机二级等级考试试题及答案No.11011.docx

    5. SQL查询:在SQL中,查询成绩在60-80分之间的学生,应该使用`BETWEEN`关键字,即`BETWEEN 60 AND 79`,选项B虽然可以达到相同效果,但标准写法应使用`BETWEEN`。 6. 类构造函数:在Java中,构造函数用于初始化类...

    2021-2022计算机二级等级考试试题及答案No.12680.docx

    - **知识点**:在SQL中,添加记录到数据库表使用`INSERT INTO`命令。 - **选项解析**:A. `ADD` 命令不适用于添加记录;C. `ALTER` 用于修改表结构;D. `ADD INTO` 的形式不正确。 ### 16. 非营利组织域名 - **知识...

    2021-2022计算机二级等级考试试题及答案No.3812.docx

    这是CSS标准的注释写法。 ### 报表视图的种类 报表视图通常包括设计视图、打印预览视图、版面预览视图等,但不包含数据表视图。数据表视图通常用于展示和编辑表中的数据。 ### 集合运算的类型 传统集合运算主要...

    2021-2022计算机二级等级考试试题及答案No.516.docx

    10. SQL查询中,查询类型为"电器"且名称包含"照相机"的商品信息,应使用LIKE操作符配合通配符,正确写法是SELECT * FROM 商品 WHERE 类型="电器" AND 名称 LIKE "*照相机*". 11. 在Java等面向对象编程中,错误的Bean...

Global site tag (gtag.js) - Google Analytics