MySQL中10个出人意料的操作结果Word文档下载推荐.docx
- 文档编号:15322926
- 上传时间:2022-10-29
- 格式:DOCX
- 页数:13
- 大小:983.75KB
MySQL中10个出人意料的操作结果Word文档下载推荐.docx
《MySQL中10个出人意料的操作结果Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《MySQL中10个出人意料的操作结果Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
b.a=a.id
6.WHERE
b.column='
something'
左连接很像内连接,但是会返回a中每条记录至少一次,如果没有找到匹配项,会将b中缺失的字段用NULL替代。
但是,WHERE条件会在左连接后执行,所以上面的查询语句在做了链接之后才检查列。
根据我们刚才知道的,NULL值是不能满足“=”条件的,所以a中有而b中没有的记录将会不可避免的被过滤掉。
事实上,这个查询除了效率不够之外,完全就是个内连接。
为了只查找b.column='
的记录(还是返回a中的所有记录),这个条件应该写成带ON的子句。
SELECT
*
FROM
a
LEFTJOIN
ON
b.a=a.id
ANDb.column='
#8.小于一个值但不是NULL
我经常看到这样的查询语句:
b
b.column<
'
ANDb.columnISNOTNULL
这其实不是一个错误:
这个查询语句正确并且会返回期望的结果。
但是,这儿的ISNOTNULL其实不需要。
如果b.column是一个NULL值,则b.column<
就不会被满足,因为任何与NULL的比较都会被评估成一个boolean类型的NULL,故不会被过滤条件通过。
很有意思的是,这个多余的NULL检查条件在大于的查询语句中从不会出现(就像b.column>
)。
这是因为在MySQL的ORDERBY条件中,NULL会被排在第一个所以一些人错误的认为NULL比其他任何值都少。
这个查询其实可以简化成:
而且不会在b.column中返回NULL。
#7.与NULL值做连接
3.JOIN
4.ON
a.column=b.column
当在两个表的列中都运行NULL值时,这个查询不会返回当两个列都为NULL的情况,原因就是NULL和NULL不相等。
下面是正确的查询语句:
5.
OR(a.columnISNULLANDb.columnISNULL)
MySQL的优化器将这视为equijoin并且提供一个特殊的连接条件,ref_or_null。
#6.NOTIN条件中的NULL值
a.*
a.columnNOTIN
(
SELECTcolumn
6.
FROM
7.
)
如果b中只有一个NULL值,这个查询不会返回任何值。
像在其他断言一样,IN和NOTIN断言中的NULL值会使得断言赋值为NULL。
这个语句应该用NOTEXISTS改写成:
NOTEXISTS
SELECTNULL
WHERE
b.column=a.column
8.
不像IN关键字,EXISTS会用true和false来赋值。
#5.随机排序样本
3.ORDERBY
RAND(),column
5.LIMIT10
这个查询尝试在一个排序列中随机选出10个记录。
ORDERBY将输出结果顺序向量排列:
即,如果第一个表达式相同,则以第二表达式的值排序。
但是,RAND()的结果是随机的,所以RAND()的结果值匹配是不可行的。
所以在RAND()操作后做排序是无用的。
为了排序随机抽样记录,用这个查询语句:
01.SELECT
02.FROM
(
03.
04.
mytable
05.
ORDERBY
06.
RAND()
07.
LIMIT10
08.
)q
09.ORDERBY
10.
column
#4.从一个分组中抽样任意一条记录
这个查询语句试图选择每个分组中的一列(grouper定义)
DISTINCT(grouper),a.*
DISTINCT不是一个函数,他是SELECT子句的一部分。
它作用于SELECT语句中的所有列,而且这里的括弧可以省略。
这个查询会选择grouper的副本(如果至少在其他一列中有不同值)。
有时,用这个查询行得通(这个查询依赖于MySQL对GROUPBY的扩展):
3.GROUPBY
grouper
每个分组中独立的列是随机抽取的。
一开始,这看起来是个好的解决方案,但是它有一个很严重的缺点。
它依赖与所有的值都会返回这样一个假设条件,虽然从分组中任意抽取,但仍然属于一个记录。
虽然目前的MySQL中看起来是这样,当时并没有相应的文档记录,并且可能在任何时候发生改变(特别是如果MySQL打算在GROUPBY后应用index_union)。
所以依赖这种行为是不安全的。
如果MySQL支持分析性函数,这个查询语句可以很容易以一种更清晰的方式改写。
但是,如果没有这些,还是有办法做这样的操作,只有这个表有定义好的主键:
DISTINCTgrouper
)ao
06.JOIN
07.ON
a.id=
09.
id
aai
11.
ai.grouper=ao.grouper
12.
LIMIT1
13.
#3.从一个分组中抽样第一个记录
这是之前查询语句的一个变种:
5.ORDERBY
MIN(id)DESC
与上面的查询语句不同,这个语句尝试选择一个有最小id号的记录。
再次申明:
不能保证a.*返回的独立值会属于一个有MIN(id)的记录(或者说属于一个记录)。
下面是怎样以一种清晰的形式操作:
ai.grouper,ai.id
14.
15.
这个查询和之前那个差不多,只是加上了ORDERBY来保证以id号排序的第一个记录会返回。
ThisqueryisjustlikethepreviousonebutwithORDERBYaddedtoensurethatthefirstrecordinidorderwillbereturned.
#2.IN和逗号分隔符的一组值列表
这个查询想要查找能够匹配下面逗号分隔符所列字符串中任何一个值的结果:
columnIN('
1,2,3'
这样做不会成功,因为字符串不能在IN列表中展开。
如果列值是VARCHAR类型的,它(以一个字符串的形式)可以和这个列表(也是以一个字符串的形式)比对,并且很显然不可能匹配上。
如果该列是数值类型,这个列表会自动转型成数值类型(最好情况是第一个项目可以转型匹配成功)。
正确的处理这个查询的方法是在合适的In列表中重写这个查询。
columnIN(1,2,3)
或者以内联视图:
1ASid
UNIONALL
2ASid
3ASid
09.JOIN
10.ON
a.column=q.id
但这并不总是可能实现。
想不改变查询参数解决这个问题我们可以用FIND_IN_SET:
FIND_IN_SET(column,'
1,2,3'
但是这个函数不可优化搜索,并且要扫描整个表a。
#1.带COUNT(*)的左连接
a.id,COUNT(*)
6.GROUPBY
a.id
这个查询希望计算每个a中记录匹配b的数量。
但问题是在这样的查询中COUNT(*)不会返回0值。
如果a中记录没有匹配项,这个记录仍将返回并计数。
COUNT应该只记b中实际记录数。
当代参数调用时,COUNT(*)忽略NULL值,我们可以传递b.a给它。
当它是一个join条件的key值时,理论
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MySQL 10 出人意料 操作 结果