如下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查询原理及其慢查询优化案例
分享到:
相关推荐
` 这一行似乎包含了一些非标准字符,正确的写法应为 `CREATE DATABASE db_name;`。 **使用数据库** 一旦创建了数据库,接下来就需要使用这个数据库来执行进一步的操作,例如创建表、插入数据等。 **语法格式:** `...
使用ODBC连接数据库通常用于非标准的数据库类型或当没有可用的JDBC驱动时。 **代码示例:** ```java // 加载ODBC驱动 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // 连接数据库 Connection ...
spool oracleday01.txt :开始记录 spool off :开始保存细节 四、SELECT语句:选择操作、投影操作。 select:从一个或多个表中检索一个或多个数据列。包含信息:想选择什么表,从什么地方选择。必须要有From...
1. **连接管理**:MySQL++提供了`sql::Connection`类,用于建立和管理与MySQL服务器的连接。通过构造函数,我们可以设置服务器地址、用户名、密码等参数,实现快速连接。 2. **查询执行**:`sql::Statement`类允许...
在大多数SQL方言中,包括MySQL、SQL Server、Oracle等,如果你的字符串内容里有一个单引号,你需要在它前面再添加一个单引号来进行转义。例如,如果你要搜索包含“标准间”的ROOMTYPE,正确的写法应该是: ```sql @...
- 整型字段根据业务需求选择合适的类型,并采用标准写法。 - 字符串类型使用`varchar`时必须指定长度,且长度通常不大于实际需求的两倍。 - 避免使用`char(m)`字符串类型。 - 默认情况下,不添加预留字段。 - 关联表...
Java开发中的JDBC(Java Database Connectivity)是一种标准的API,允许Java程序与各种数据库进行交互。JDBC提供了统一的接口,使得开发者无需关心底层数据库的差异,只需编写相对通用的代码即可实现对不同数据库的...
当你去掉单引号后,语句意外地成功了,这是因为MySQL默认情况下允许在没有引号的情况下直接比较非数字字段,但这并不推荐,因为它可能导致解析歧义或安全问题。 至于图形界面生成的代码: ```sql UPDATE `web`.`...
从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提供的一个组件,...
12. 良好的编程实践:在设计程序时,应遵循使程序结构易于理解的原则,以提高代码的可读性和维护性,而非追求代码长度或限制特定语句的使用。 13. 主键的错误叙述:主键不能有重复值,不能为 NULL,且一个表可以有...
10. SQL语句用来添加职工号字段的有效性规则是ALTER TABLE语句,正确的写法是`ALTER TABLE 教师 ALTER 职工号 SET CHECK LEFT(职工号,3)="110"`。 11. 菜单后面的快捷键组合,如Ctrl+P,可以直接按下组合键执行相应...
5. SQL查询:在SQL中,查询成绩在60-80分之间的学生,应该使用`BETWEEN`关键字,即`BETWEEN 60 AND 79`,选项B虽然可以达到相同效果,但标准写法应使用`BETWEEN`。 6. 类构造函数:在Java中,构造函数用于初始化类...
- **知识点**:在SQL中,添加记录到数据库表使用`INSERT INTO`命令。 - **选项解析**:A. `ADD` 命令不适用于添加记录;C. `ALTER` 用于修改表结构;D. `ADD INTO` 的形式不正确。 ### 16. 非营利组织域名 - **知识...
这是CSS标准的注释写法。 ### 报表视图的种类 报表视图通常包括设计视图、打印预览视图、版面预览视图等,但不包含数据表视图。数据表视图通常用于展示和编辑表中的数据。 ### 集合运算的类型 传统集合运算主要...
10. SQL查询中,查询类型为"电器"且名称包含"照相机"的商品信息,应使用LIKE操作符配合通配符,正确写法是SELECT * FROM 商品 WHERE 类型="电器" AND 名称 LIKE "*照相机*". 11. 在Java等面向对象编程中,错误的Bean...