当前位置: 首页 > news >正文

MySQL DQL 数据查询

文章目录

  • 1.SELECT 语句
  • 2.SELECT 子句
  • 3.FROM 子句
  • 4.WHERE 子句
  • 5.GROUP BY 子句
  • 6.HAVING 子句
  • 7.ORDER BY 子句
  • 8.LIMIT 子句
  • 9.DISTINCT 子句
  • 10.UNION 子句
  • 11.查看数据表记录数
  • 12.检查查询语句的执行效率
  • 13.查看 SQL 执行时的警告
  • 14.查看自增主键最大值
  • 参考文献

1.SELECT 语句

MySQL 的 SELECT 语句用于从数据库表中检索数据。功能强大,语句结构复杂多样。不过基本的语句格式像下面这个样子。

SELECT[列名称]FROM[表名称]WHERE[条件]

一个完整的 SELECT 语句包含一些可选的子句。SELECT 语句定义如下:

SELECTclause[FROMclause][WHEREclause][GROUPBYclause][HAVINGclause][ORDERBYclause][LIMITclause]
  1. SELECT 子句是必选的,其它子句是可选的。

一个 SELECT 可以在不引用任何表的情况下进行计算,也就是没有其他任何字句,只有 SELECT 子句。

SELECT1+1ASsum;+-----+|sum|+-----+|2|+-----+
  1. 一个 SELECT 语句中,子句的顺序是固定的。如 GROUP BY 子句不会位于 WHERE 子句前面。
  2. SELECT 语句不同子句的执行顺序:
开始>FROM子句>WHERE子句>GROUPBY子句>HAVING子句>SELECT子句>ORDERBY子句>LIMIT子句>最终结果

每个子句执行后都会产生一个中间数据结果,即所谓的临时视图,供接下来的子句使用,如果不存在某个子句则跳过。

需要注意的是,不同的数据库管理系统可能会有一些差异,但一般情况下,上述顺序适用于大多数SQL查询。

MySQL 和标准 SQL 执行顺序基本是一样的。

2.SELECT 子句

SELECT 子句用于指定要选择的列或使用表达式生成新的值。

对于所选数据,还可以添加一些修饰,比如使用 DISTINCT 关键字用于去重。

一个完整的 SELECT 子句组成如下。

SELECT[ALL|DISTINCT|DISTINCTROW][HIGH_PRIORITY][STRAIGHT_JOIN][SQL_SMALL_RESULT][SQL_BIG_RESULT][SQL_BUFFER_RESULT][SQL_NO_CACHE][SQL_CALC_FOUND_ROWS]select_expr[,select_expr]...[into_option]into_option: {INTOOUTFILE'file_name'[CHARACTERSETcharset_name]export_options|INTODUMPFILE'file_name'|INTOvar_name[,var_name]...}

其中 select_expr 是必选的,表示要查询的列、表达式或使用 * 表示所有列。

SELECT*FROMt1INNERJOINt2...

可以对列使用函数进行运算,并使用 AS 关键字对结果列命名(AS 是可选的,可以省略)。

SELECTAVG(score)ASavg_score,t1.*FROMt1...# 或SELECTAVG(score)avg_score,t1.*FROMt1...

3.FROM 子句

FROM 子句指示要从中检索行的表。如果为多个表命名,则执行连接。对于指定的每个表,您可以选择指定一个别名。

FROMtable_references[PARTITIONpartition_list]

SELECT 支持显式分区选择,使用 PARTITION 子句,在 table_references 表的名称后面跟着一个分区或子分区列表(或两者都有)在这种情况下,只从列出的分区中选择行,而忽略表的任何其他分区。关于分区可参考 Chapter 24 Partitioning。

4.WHERE 子句

如果给定 WHERE 子句,则指示行必须满足的一个或多个条件才能被选中。where_condition 是一个表达式,对于要选择的每一行,其计算结果为 true 才会被选择。如果没有 WHERE 子句,将选择所有行。

[WHERE condition]

下面的运算符可在 WHERE 子句的条件表达式中使用。

运算符描述
=等于
!= 或 <>不等于
>大于
<小于
>=大于等于
<=小于等于
BETWEEN AND在某个范围内(闭区间)
LIKE搜索某种模式
AND多个条件与
OR多个条件或

(1)WHERE IN 的用法

IN 在 WHERE 子句中的用法主要有两种:

  • IN 后面是子查询产生的记录集,注意,子查询结果数据列只能有一列且无需给子查询的结果集添加别名。
SELECT*FROMtbl_name1WHEREcol_name1IN(SELECTcol_name2FROMtbl_name2);
  • IN 后面是数据集合。
SELECT * FROM tbl_name WHERE col_name IN ('foo', 'bar', 'baz', 'qux');

注意:如果数据类型是字符串,一定要将字符串用单引号引起来。

5.GROUP BY 子句

GROUP BY 子句是 SQL 中用于对数据进行分组聚合的核心功能。它将查询结果按照一个或多个列的值分成不同的组,然后对每一组应用聚合函数(如 SUM、AVG、COUNT、MAX、MIN 等),最终每个组返回一行汇总结果。

核心作用:

  • 数据分组:将具有相同值的记录归类到同一组中;
  • 为聚合计算划定范围:聚合函数会在每个分组内独立计算,而不是针对整个表;
  • 减少结果集行数:原始表中的多行数据,按分组条件压缩成一行汇总结果。

基本语法:

SELECT分组列1,分组列2,聚合函数(列名)AS别名FROM表名WHERE条件GROUPBY分组列1,分组列2;

执行顺序:WHERE → GROUP BY → 聚合计算 → HAVING → SELECT → ORDER BY。

示例:

-- 选择发起加好友请求次数超过10次的 QQ(uin),被加方(to_uin)只会显示第一个SELECTuin,to_uin,count(*)AScntfrominner_raw_add_friend_20170514GROUPBYuinHAVINGcnt>10;

如果指定多列,使用逗号分隔。

GROUPBYcol1,col2,...

注意:GROUP BY 子句中的数据列应该是 SELECT 指定的所有数据列,除非这列用于聚合函数。但是,如果 SELECT 指定的数据列,没有用于聚合函数也不在 GROUP BY 子句中,按理说会报错,但是 MySQL 会选择第一条显示在结果集中。

6.HAVING 子句

HAVING 和 WHERE 子句一样,用于指定选择条件。但 HAVING 和 WHERE 子句的用法上却有明显的区别。

  1. 作用的对象不同。

WHERE 作用于表和视图,HAVING 作用于组。

# 查询 QQ 3585076592 和 3585075773 在 20170514 当天加好友请求次数且请求次数>10SELECTuin,count(*)AScntFROMinner_raw_add_friend_20170514WHEREuin=3585076592ORuin=3585075773GROUPBYuinHAVINGcnt>10;
  1. 作用的阶段不同。

WHERE 在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算),而 HAVING 在分组和聚集之后选取分组。因此,WHERE 子句不能包含聚集函数,因为试图用聚集函数判断哪些行输入给聚集运算是没有意义的。 相反,HAVING 子句一般包含聚集函数。当然,也可以使用 HAVING 对结果集进行筛选,但不建议这样做,同样的条件可以更有效地用于 WHERE 阶段。

# 查询指定 QQ 加好友请求信息(where作用于输入阶段的数据集)SELECT*FROMinner_raw_add_friend_20170514WHEREuin=3585078528;# 作用等同于 WHERE, 但 HAVING 作用于结果阶段的结果集SELECT*FROMinner_raw_add_friend_20170514HAVINGuin=3585078528;

7.ORDER BY 子句

ORDER BY 子句用于根据指定的列对结果集进行排序。

[ORDERBY{col_name|expr|position}[ASC|DESC],...[WITH ROLLUP]]

ORDER BY 语句默认按照升序 ASC(ascend)对记录进行排序。如果希望按照降序排序,可以使用 DESC(descend)关键字,随机使用随机数函数RAND()

在指定待排序的列时,不建议使用列位置(从1开始),因为该语法已从SQL标准中删除。

比如以 QQ 号码降序排序。

SELECT*FROMinner_raw_add_friend_20170514ORDERBYuinDESC;

8.LIMIT 子句

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。

[LIMIT{[offset,]row_count|row_countOFFSEToffset}]

LIMIT 接受一个或两个数值参数。参数必须是一个整数常量。如果给定两个参数,有两种用法。

offset,row_count# 或row_countOFFSEToffset

offset 为返回记录行的开始偏移量,从 0 开始,row_count 为返回记录行的最大数目。

只给一个参数,表示返回记录行的 Top 最大行数,起始偏移量默认为 0。

返回从起始偏移量开始,返回剩余所有的记录,可以使用一些值很大的第二个参数。如检索所有从第 96 行到最后一行。

SELECT*FROMtblLIMIT95,18446744073709551615;

注意,MySQL目前不支持使用 -1 表示返回从偏移量开始剩余的所有记录,即下面的写法是错误的:

SELECT*FROMtblLIMIT95,-1

9.DISTINCT 子句

DISTINCT 关键字用于查询结果中去除重复的行,只返回唯一的行。

(1)利用 DISTINCT 结合 COUNT() 函数可以统计不重复记录的数量。

# 选择每一个 QQ 发起加好友请求涉及到的不同的 QQ 数SELECTuin,count(distinctto_uin)cFROMadd_friendGROUPBYuin;

(2)DISTINCT 用于选择不同的记录,且只能放在所选列的开头,作用于紧随其后的所有列。

# 查询 uin 和 to_uin 不重复的加好友请求SELECTDISTINCTuin,to_uinFROMadd_friend;# 示例数据表uin to_uin10000123456100001212121000112121210001131313# 结果集uin to_uin10000123456100001212121000112121210001131313

如果想使 DISTINCT 的功能作用于第二列的 to_uin,使用 DISTINCT 是无望了,因为 MySQL 语法尚不支持,可以使用 GROUP BY 取而代之。

SELECTuin,to_uinFROMadd_friendWHEREGROUPBYto_uin;# 结果集uin to_uin100001234561000012121210001131313

该奇技淫巧只能用在 MySQL,因为标准的 SQL 语法规定非聚合函数中的列一定要在 GROUP BY 子句中。MySQL 规定,当非聚合函数中的列不存在于 GROUP BY 子句中,则选择每个分组的第一行。

(3)COUNT DISTINCT 统计符合条件的记录数量。

如果像对符合条件的记录进行 COUNT DISTINCT,那么如何添加条件呢?

参见 MySQL distinct count if conditions unique,可以使用下面的方法。

COUNT(DISTINCTCASEWHEN条件THEN字段END)

参见 mysql count if distinct,也可以使用下面这种方法。

COUNT(DISTINCTcol_name1,IF(col_name2=1,true,null))

10.UNION 子句

UNION 的作用是将两次或多次查询结果纵向合并起来。

query_expression_bodyUNION[ALL|DISTINCT]query_block[UNION[ALL|DISTINCT]query_expression_body][...]

下面是一个示例。

mysql>SELECT1,2;+---+---+|1|2|+---+---+|1|2|+---+---+mysql>SELECT'a','b';+---+---+|a|b|+---+---+|a|b|+---+---+mysql>SELECT1,2UNIONSELECT'a','b';+---+---+|1|2|+---+---+|1|2||a|b|+---+---+

使用 UNION 需要注意以下几点。

(1)UNION 的使用条件

UNION 只能作用于结果集,不能直接作用于原表。结果集的列数相同就可以,即使字段类型不相同也可以使用。值得注意的是 UNION 后字段的名称以第一条 SQL 为准。

(2)UNION 与 UNION ALL 的区别

UNION 用于合并两个或多个 SELECT 语句的结果集,并消去合并后的重复行。UNION ALL 则保留重复行。

(3)关于 UNION 的排序

有两张表,内容如下:

# table1 uin nickname 10001 monkey 10002 monkey king # table2 uin nickname 20000 cat 20001 dog

对两个结果集按照 uin 进行降序排序后再联合。

(SELECT*FROMtable1ORDERBYuinDESC)UNION(SELECT*FROMtable2ORDERBYuinDESC);uin nickname10001monkey10002monkey king20000cat20001dog

可以发现,内层排序没有发生作用,那现在试试在外层排序。

SELECT*FROMtable1UNIONSELECT*FROMtable2ORDERBYuinDESC;uin nickname20001dog20000cat10002monkey king10001monkey

可见外层排序发生了作用。那是不是内层排序就没有用了呢,其实换个角度想想内层先排序,如果外层又排序,明显内层排序显得多余,所以 MySQL 优化了 SQL 语句,不让内层排序起作用。要想内层排序起作用,必须要使内层排序的结果能影响最终的结果,如加上 LIMIT。

(SELECT*FROMtable1ORDERBYuinDESCLIMIT2)UNION(SELECT*FROMtable2ORDERBYuinDESCLIMIT2);uin nickname10002monkey king10001monkey20001dog20000cat

此外,UNION 与 JOIN 在使用时,有一个本质区别我们必须知道。

UNION 只能作用于 SELECT 结果集,不能直接作用于数据表,而 JOIN 则恰恰相反,只作用于数据表,不能直接作用于 SELECT 结果集(可以将 SELECT 结果集指定别名作为派生表)。

11.查看数据表记录数

查看数据表行数有多种方法。

  1. 使用 COUNT(*)
SELECTCOUNT(*)FROMtbl_name;

对于 MyISAM 数据表很快,建议使用,因为 MyISAM 数据表事先将行数缓存起来,可直接获取。InnoDB 数据表不建议使用,当数据表行数过大时,因需要扫描全表,查询较慢。

  1. 查看系统表 information_schema.TABLES
SELECTtable_rowsFROMinformation_schema.TABLESWHERETABLE_SCHEMA='db_name'ANDTABLE_NAME='tbl_name';

information_schema 是 MySQL 中的一个系统数据库,它包含了关于数据库、表、列等元数据信息。可以通过查询 information_schema.TABLES 表可以获取指定数据表的记录数。

  1. 使用 SHOW TABLE STATUS 命令
SHOWTABLESTATUSLIKE'tbl_name';

需要注意的是,SHOW TABLE STATUS 命令返回的行数是一个近似值,并不是实时的准确值。这是因为 MySQL 在某些情况下会对行数进行估算,而不是实时计算。如果需要准确的行数,建议使用 COUNT(*) 函数或查询 information_schema.TABLES 视图。

12.检查查询语句的执行效率

EXPLAIN 是一个用于查询优化的工具,它可以提供有关 SELECT 查询的执行计划的详细信息。通过使用 EXPLAIN 命令,可以了解 MySQL 是如何执行查询的,包括使用的索引、连接类型、扫描的行数等。

{EXPLAIN|DESCRIBE|DESC} select_statement;

EXPLAIN 命令的输出结果包含以下列:

id:查询的标识符,用于标识查询中的每个步骤。 select_type:查询的类型,如 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。 table:查询涉及的表。 partitions:查询涉及的分区。 type:访问表的方式,如 ALL(全表扫描)、INDEX(使用索引扫描)、RANGE(范围扫描)等。 possible_keys:可能使用的索引。 key:实际使用的索引。 key_len:使用的索引的长度。 ref:与索引比较的列或常量。 rows:扫描的行数。 filtered:过滤的行百分比。 Extra:额外的信息,如使用了临时表、使用了文件排序等。

13.查看 SQL 执行时的警告

SHOW WARNINGS 是一个用于查看最近一次执行的语句产生的警告信息的命令。在 MySQL 中,警告(Warning)是一种表示潜在问题或异常情况的消息,它不会导致语句的执行失败,但可能会影响到查询结果或性能。

SHOWWARNINGS;

SHOW WARNINGS 命令的输出结果包含以下列:

Level:警告的级别,如 Warning、Note 等。 Code:警告的代码。 Message:警告的具体消息。

通过查看警告信息,可以了解到语句执行过程中可能存在的问题或异常情况,如截断数据、丢失数据等。根据警告信息,可以进行相应的调整和处理,以确保查询的正确性和性能。

14.查看自增主键最大值

  • 使用 MAX 函数。
SELECTMAX(id)FROMyour_table_name;
  • 查看表状态
SHOWTABLESTATUSLIKE'your_table_name';

在查询结果中,您可以查找 Auto_increment 列,它将显示自增主键的下一个值。


参考文献

MySQL 8.0 Reference Manual :: 13.2.13 SELECT Statement
MySQL 8.0 Reference Manual :: 13.2.18 UNION Clause
MySQL 8.0 Reference Manual :: 13.2.13.2 JOIN Clause
MySQL 8.0 Reference Manual :: 13.8.2 EXPLAIN Statement
8.8.1 Optimizing Queries with EXPLAIN

http://www.cnnetsun.cn/news/4251058.html

相关文章:

  • 2026年度国自然申报全流程要点梳理与避错指南
  • 大模型算法岗常见面试题100道(值得收藏)
  • 具身智能投资热潮:聪明钱究竟在争夺什么?
  • 国君产业研究汽车报告|大模型赋能座舱,智能座舱新战场(附PDF)
  • 大模型API开发中的thought traces:可解释性、调试与工程实践
  • 【行业】AI大爆发时代,巨头下场!互联网+医疗服务模式正加速创新!
  • 容器变慢先查限流和请求排队
  • 王兴兴与梁文锋“错配”背后:具身智能与大模型的真实差距
  • Wine Ubuntu 调用 Windows 应用
  • 2024请收好这一份全面且详细的AI产品经理从业指南,错过会后悔!!
  • 资深开发 / 架构师|3 个月可执行学习实践计划表
  • 中年中产程序员春节低成本自驾游:从西安出发到深圳阳江海陵岛,海南岛10天深度度假游(1)-- 海陵岛
  • 【AI大模型】写给小白的大模型应用科普:RAG篇
  • 存量系统迁移,用小变更保持主干可用
  • RustDesk部署到linux(自建服务器)
  • python的图论工业场景模拟第三篇:电力网架连通分量与孤岛区域诊断,任务解析电力网络图,找出因开关跳闸形成的孤立供电区(连通分量),图建模说明,无向图,节点=配电节点,边=闭合的开关。
  • 设计开发协作的令牌化落地方法
  • 万字长文!一文了解归一化:从Transformer归一化到主流大模型归一化的演变!
  • AutoClicker
  • 小白学大模型:提示词工程(Prompt)与Agent,简单易懂,轻松拿捏!!
  • 2026年亲测最值得推荐的5款降AI率工具
  • 2026年云台摄像头口碑榜 高好评家用产品特点与选购参考
  • Grok刷屏解析:从聊天模型到AI执行体的工程接入指南
  • 拖入 main.dat 就开始改:动物森友会存档编辑五步上手
  • 【收藏级干货】用AI大模型实现量化策略:内联编辑器实战教程
  • AgentClinic:模拟临床医疗环境的多模态大模型智能体评估基准,建议收藏起来慢慢看!!
  • 如何3分钟上手DSH Desktop:从下载macOS安装包到第一次官方DSH会话
  • 【AI大模型】RL反常识研究,直接给LLM喂答案比提供详细步骤更有用!
  • AI 大模型应用架构演进: LLM → RAG → AI Workflow → AI Agent
  • pure-python-adb 插件体系深度解析:6大内置插件监控CPU、内存、电池与流量