mysql选择性查询_MySQL 查询操作

mysql中查询的关键字是SELECT,其完整语法为:(下面会分别介绍每个段的用法,可以先看后面的再回过头看前面)

SELECT

DISTINCT

FROM

JOIN

ON

WHERE

GROUP BY

HAVING

ORDER BY LIMIT

要提一下的是,为了高效操作,一条语句中每步的操作都会产生一个虚表,下一步即对这个虚表进行操作,虚表会在内部自动生成和删除。

查询语句很多时候绕的晕,其实是你不熟悉每条语句的执行顺序。在引擎内部的语句执行的顺序和语法写的顺序是不一样的,下面看看select机器内部的执行顺序:

1. FROM #先对表进行笛卡尔乘积,得到虚表T1

2. ON #对T1进行条件筛选,得到T2

3. JOIN #根据连接类型,对T2进行信息补充,比如left join,左边表未匹配到的部分会适当添加NULL后加入到T2中,形成T3

4. WHERE #对T3进行筛选,得到T4

5. GROUP BY #根据要分组的列,对T4进行分组,得到T5

6. HAVING #对T5进行筛选,得到T6

7. SELECT #这时才选择列,选择T6中指定的列,得到T7

8. DISTINCT #对T7除重 得到T8

9. ORDER BY #对T8 进行排序 得到T9

10. LIMIT #对T9进行截取,得到最终结果

基本查询

查询表中的某列,多个列名可以用逗号分隔,所有列可以用 * 代替,语法:

SELECT list_name1,list_name2 … FROM table_name;

eg:SELECT * FROM students; #查看学生表

3b5fab5216ca27ae47e1897b4e4c45b6.png

选择性查询

选择性的查询记录,通过where子句,进行字段的精确筛选。语法如下:

SELECT * FROM table_name WHERE ;

eg: SELECT * FROM students WHERE score >= 80 AND gender = 'M';

664ed7f04520bc55c0f406a405b65507.png

除了可以用<>=等运算符进行筛选,还可以使用BETWEEN,如where score BETWEEN 0 AND 60;筛选不及格记录。

用于where条件组合的四个操作符:AND、OR、IN、NOT。

IN用来指定条件范围,符合的条件都在括号内用逗号隔开,如where score IN(100,60);可以筛选满分和刚好及格的记录。IN比OR快。NOT用于否定条件,如前面语句改为NOT IN,筛选的就是及格的记录。

筛选过滤还可以采用通配符,关于LIKE、正则表达式见 MySQL 其他常用语法。

子查询

查询可以嵌套,即可以查询另一个查询的结果。

SELECT * FROM(SELECT * FROMstudentsWHERE scour<60)WHERE gender='M';

上面的语句当然可以用1条select完成,这里只是展示其用法。当业务需求复杂时,如从多个表获取信息时,子查询是十分灵活的选择。

聚合查询

使用聚合函数进行对数据汇总的查询。聚合函数有5个,COUNT、SUM、AVG、MAX、MIN。

比如统计一张表符合筛选条件的记录数,用COUNT()函数。格式为COUNT([DISTINCT|ALL] ),DISTINCT表示不统计重复项,默认为ALL统计重复项。

SELECT COUNT(*) num FROM students;   统计表中记录条数,返回一个2*1的二维表,字段名为numSELECT COUNT(id) boys FROM students WHERE gender = 'M';   where执行在select之前,因此count统计的是筛选后的数据,结果如下

4b29554ceb896591fa98e5d7af9cde82.png

·count():count(list)统计list不为null的记录数;count(*)统计所有的记录数,null也会被统计,因为主键不会为null,相当于统计主键个数。

·avg()、sum()、max()、min():需要指定列名,也会忽略null。

分组查询

用GROUP BY对查询结果按字段列表进行分组,字段值相等的记录分为一组;语法如下:

[GROUP BY 字段列表] [HAVING ],HAVING用于过滤组,仅输出满足条件的组。

使用分组需要注意:

· NULL也会作为一个分组返回。

· GROUP BY中列出的每个列只能是检索列或有效表达式,不能是聚集函数。

· 除了聚集函数外,SELECT中列出的每个列也都必须在GROUP BY中列出。

比如现在想知道每个班的人数,可以这样做:

SELECT COUNT(*) num FROM students GROUP BY class_id;  按班级分组,count是对每组进行计数

SELECT class_id, COUNT(*) num FROM students GROUP BYclass_id;   可以把class_id列也放入结果集

查出每个班级的平均分,并只看平均分高于80的班级,语句如下,结果如图:SELECT class_id, AVG(score) avgscore FROM students GROUP BY class_id HAVING AVG(score)>80;

5fbe082ef0eb21957957699e4244553a.png

having和where不同,where是过滤记录,having是过滤组,where在分组前就过滤完,having在分组后过滤。

多表查询

mysql还可以同时查询多个表,得到的结果整合到一张表里,即students表的每一行与classes表的每一行都两两拼在一起返回。结果集的列数是students表和classes表的列数之和,行数是students表和classes表的行数之积。这种查询叫笛卡尔查询,又称交叉查询。

SELECT * FROM students, classes;

一般这样查询的结果,很多记录是没有意义的。如上语句,如果没有筛选,那么会出现小明既在一班又在其他班的记录,这明显是错误的。多表查询,表之间肯定是有某种联系联合起来才有意义,因此多表查询一般必须添加联结条件。上例中,学生表和班级表的联系就是class_id,正确的写法:

SELECT s.name name,gender,c.name classname from students s,classes c where s.class_id=c.id;

217ce827581bc7fdbc93a7ef28ab9867.png

连接查询

很多时候多张表之间是有联系的,它们可能有相同的列,因此可以联结多个表进行查询。连接查询也是多表查询,通常使用多表查询时优先用连接查询,而不是上面介绍的多表查询。

语法:SELECT FROM JOIN ON ;

连接的规则有两种:

· 内连接INNER JOIN:join前加inner关键字,不加的话,默认join也为内连接。返回笛卡尔积中符合连接条件的数据行,和上述的多表查询是一样的,不过SQL推荐使用联结写法,这样能避免忘记填写筛选条件。

· 外连接:又分三种;

· 左连接LEFT OUTER JOIN:通过ON条件筛选后,将左表中其余未在结果中展示的记录也添加进来,空的字段补NULL。

· 右连接RIGHT OUTER JOIN:类似左连接,补齐右表中的所有记录。

· 全连接FULL OUTER JOIN:左表和右表的所有行数据都补齐,空的地方填NULL。

其中INNER和OUTER关键字可以省略,但使用全连接时不能省略。

值得注意的是,如果没有ON筛选,那么结果就是笛卡尔积。

内连接和上述多表连接产生相同效果,下面举例理解一下外连接,假如新学期开学了,二班的同学都毕业了,学校撤销了二班,并且新增了一个五班,有两名同学在五班念书,学校的管理混乱,只更新了students表。此时students表如下:

5ccc9e45ab879b31c04e64290f71fcf5.png

classes表如下:

9a243ad998fcf6d82d6bef2a05542c5f.png

此时我们如果想将班级信息和学生信息统计在一张表,如果使用内连接,筛选条件为students.class_id=classes.id,那么新入学的柯基和二哈就不会显示。此时如果使用外连接,可以选择补齐哪个表的未匹配记录。

左连接

SELECT students.name,gender,classes.name FROM students LEFT JOIN classes ON students.class_id=classes.id;

#一个表不允许重复的列名,因此将class的name重命名为classname;

#由下图可以看到,前7条记录是由ON筛选出来的,后两条是因为left join额外补齐的。

9d00b8c0c754ea5b2012497af08622b6.png

那么右连接和全连接的结果就很容易能想到了。

组合查询

组合查询通过UNION将多个SELECT查询结果组合到一张表中返回。

语法:SELECT … FROM … UNION SELECT … FROM … ORDER BY … LIMIT … ;

值得注意的是:

· 组合的两个select表需要有相同的列,聚合函数和表达式,不过它们的列可以顺序不同;

· 列的类型必须兼容,不必完全相同,但必须是可以隐式转换的类型。例如TINYINT和INT;

· 默认组合会去除重复的记录,即两个表中都有的记录。可以通过在UNION后加ALL关键词显示重复记录;

· ORDER是对组合后的结果进行排序,只允许有一个ORDER,且必须在最后。

排序

查询的结果集通常是按照表中实际存放顺序排序的,但可以自定义条件排序。通过ORDER BY命令可以指定通过什么字段排序,比如通过score排序:

SELECT * FROM students ORDER BY score;

默认是按照升序排序,也可以指定为降序ORDER BY score DESC;

可以对多列进行排序,即第一个排序条件相同时,比较后面的排序条件;

如果有WHERE子句,ORDER子句要放到其后面,逻辑上就是在筛选出的记录中排序。

分页

数据太多可以分页查看,M表示最多显示M条记录,N表示偏移量。LIMIT永远在语句最后,其语法是:

LIMIT OFFSET ;eg:SELECT * FROM students LIMIT 3 OFFSET 6;  表示显示3条记录,偏移6条记录,从第7条记录开始

还可以省略offset写成:LIMIT m,n; 表示偏移m条显示n条

参考:廖雪峰的SQL教程 、《MySQL必知必会》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在MySQL查询语句中,如果使用了GROUP BY子句,并且在SELECT子句中引用了非聚合列,会出现"ERROR 1140 (42000): In aggregated query without GROUP BY"错误,这是由于MySQL的默认设置是开启了ONLY_FULL_GROUP_BY模式,要避免此错误,可以采取以下几种方法。 1. 使用聚合函数:将所有的非聚合列都使用聚合函数进行处理,例如使用MAX()、MIN()、SUM()等函数。 2. 在SELECT子句中列出所有的非聚合列:将非聚合列都在SELECT子句中列出,作为GROUP BY子句的一部分。 3. 使用任意值函数:使用任意值函数如ANY_VALUE()可以欺骗MySQL,使其认为不需要严格的GROUP BY限制,但需要注意的是,这样做可能会导致在结果中随机返回值。 4. 修改SQL模式:可以通过修改MySQL的SQL模式来规避ONLY_FULL_GROUP_BY,可以通过以下命令来修改: SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); 需要注意的是,修改SQL模式会影响全局的MySQL设置,可能对其他查询产生影响,所以在修改前请谨慎考虑。 总之,要规避ONLY_FULL_GROUP_BY错误,可以使用聚合函数、列出所有的非聚合列、使用任意值函数或修改SQL模式等方法。具体选择哪种方法要根据实际情况来决定。 ### 回答2: MySQL中的`ONLY_FULL_GROUP_BY`是一个SQL模式,用于控制GROUP BY查询的行为是否严格遵守标准。当启用`ONLY_FULL_GROUP_BY`模式时,任何SELECT语句中,SELECT列表中的非聚合列必须在GROUP BY子句中,或者作为聚合函数的参数。 为了规避`ONLY_FULL_GROUP_BY`,有以下几种方法: 1. 使用聚合函数:将非聚合列作为聚合函数的参数来解决。例如,使用`MAX()`、`MIN()`、`SUM()`等聚合函数对非聚合列进行聚合操作。 2. 使用子查询:将GROUP BY查询作为子查询,然后在外部查询中进行对非聚合的列的处理。例如,首先对数据进行GROUP BY操作,然后再在外部查询中使用聚合函数或其他方式对非聚合列进行处理。 3. 使用ANY_VALUE()函数:`ANY_VALUE()`函数可以允许非聚合的列出现在SELECT列表中,并避免`ONLY_FULL_GROUP_BY`错误。它返回一个组内某个非聚合列的任意值。 需要注意的是,根据业务需求和数据一致性,必须确保使用这些方法不会导致数据错误或不一致。因此,在使用这些方法之前,应仔细审查查询逻辑和数据的逻辑关系。另外,可以考虑将`ONLY_FULL_GROUP_BY`模式设置为严格模式,以确保查询的准确性和一致性。 ### 回答3: MySQL的"only_full_group_by"模式是在执行GROUP BY语句时的一个严格模式,要求SELECT语句中的列要么在GROUP BY子句中进行聚合,要么在SELECT列表中作为GROUP BY中的列。如果查询中出现了不符合该要求的列,MySQL会报错。 要规避"only_full_group_by"模式,可以使用以下方法: 1. 使用合适的聚合函数:将所有的非聚合列都替换为合适的聚合函数,如SUM、MAX、MIN、AVG等。这样就不需要在GROUP BY子句中进行聚合,也符合"only_full_group_by"模式的要求。 2. 使用任意值函数:可以使用任意值函数(如ANY_VALUE)来替代非聚合列。这样MySQL会随机选择一个值,作为非聚合列的值。虽然这样可能会导致结果不准确,但可以规避"only_full_group_by"模式。 3. 添加合理的GROUP BY子句:将所有的SELECT列表中的列都添加到GROUP BY子句中。这样可以确保每个非聚合列都在GROUP BY中,并符合"only_full_group_by"模式的要求。 需要注意的是,如果使用了上述方法规避了"only_full_group_by"模式,可能会导致查询结果不准确。所以在使用时需要根据具体的业务需求和数据特点来确定是否需要规避该模式,以及选择合适的方法进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值