SQL 必知必会
陈旸
清华大学计算机博士
73337 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
第一章:SQL语法基础篇 (19讲)
SQL 必知必会
15
15
1.0x
00:00/00:00
登录|注册

05丨检索数据:你还在SELECT * 么?

去除重复行
查询常数
起别名
查询列
什么情况下用SELECT*
SELECT的执行顺序
约束返回结果的数量
如何排序检索数据
SELECT查询的基础语法
SQL检索数据

该思维导图由 AI 生成,仅供参考

今天我们主要学习如何使用 SQL 检索数据。如果你已经有了一定的 SQL 基础,这节课可以跳过,也可以把它当做是个快速的复习。
SELECT 可以说是 SQL 中最常用的语句了。你可以把 SQL 语句看作是英语语句,SELECT 就是 SQL 中的关键字之一,除了 SELECT 之外,还有 INSERT、DELETE、UPDATE 等关键字,这些关键字是 SQL 的保留字,这样可以很方便地帮助我们分析理解 SQL 语句。我们在定义数据库表名、字段名和变量名时,要尽量避免使用这些保留字。
SELECT 的作用是从一个表或多个表中检索出想要的数据行。今天我主要讲解 SELECT 的基础查询,后面我会讲解如何通过多个表的连接操作进行复杂的查询。
在这篇文章中,你需要重点掌握以下几方面的内容:
SELECT 查询的基础语法;
如何排序检索数据;
什么情况下用SELECT*,如何提升 SELECT 查询效率?

SELECT 查询的基础语法

SELECT 可以帮助我们从一个表或多个表中进行数据查询。我们知道一个数据表是由列(字段名)和行(数据行)组成的,我们要返回满足条件的数据行,就需要在 SELECT 后面加上我们想要查询的列名,可以是一列,也可以是多个列。如果你不知道所有列名都有什么,也可以检索所有列。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文详细介绍了SQL中SELECT查询的基础语法、排序检索数据以及约束返回结果数量的方法。在基础语法部分,文章讲解了单列、多列和使用SELECT * 检索所有列的方法,以及给列名和表名称起别名的技巧。此外,还介绍了如何使用DISTINCT关键字去除重复行。在排序检索数据方面,文章详细讲解了使用ORDER BY子句对结果进行排序的方法,包括排序的列名、排序的顺序以及非选择列排序的使用。最后,文章介绍了如何使用LIMIT关键字约束返回结果的数量,并提到了在不同的DBMS中使用LIMIT关键字的不同方式。此外,还对SELECT查询的执行顺序进行了解释,以及在实际应用中如何提升SELECT查询效率。总的来说,本文内容详实,适合读者快速了解SQL检索数据的基础知识,对于数据库操作有一定了解的读者可以作为快速复习的资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《SQL 必知必会》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(163)

  • 最新
  • 精选
  • 君莫惜
    置顶
    SELECT COUNT(*) > SELECT COUNT(1) > SELECT COUNT(具体字段) 之前看到的,好像Mysql对count(*)做了单独的优化

    作者回复: 关于COUNT()的效率是一个很好的问题,欢迎探讨: 在MySQL InnoDB存储引擎中,COUNT(*)和COUNT(1)都是对的所有结果进行的COUNT。如果有WHERE子句,则是对所有符合筛选条件的数据行进行统计。如果没有WHERE子句,则是对数据表的数据行数进行统计。 因此COUNT(*)和COUNT(1)本质上没有区别,执行的复杂度都是O(N),也就是采用全表扫描,进行循环+计数的方式进行统计。 如果是MySQL MyISAM存储引擎,统计数据表的行数只需要O(1)复杂度,这是因为每张MyISAM的数据表都有一个meta信息有存储了row_count值。而一致性由表级锁来保证。而InnoDB支持事务,采用行级锁和MVCC机制,所以无法像MyISAM一样,只维护一个row_count变量。因此就需要采用扫描全表,进行循环+计数的方式来完成统计。 需要注意的是,在实际执行中COUNT(*)和COUNT(1)执行时间可能略有差别,不过你还是可以把这两个在执行效率上看成是相等的。 另外在InnoDB引擎中,如果是采用COUNT(*)和COUNT(1)来统计数据行数,要尽量采用二级索引。 因为主键采用的索引是聚簇索引,聚簇索引包含的信息多,明显会大于二级索引(非聚簇索引)。 对于查找具体的行来说,采用主键索引效率更高。而对于COUNT(*)和COUNT(1)这种,不需要查找具体的行,只是统计行数来说,系统会自动采用占用空间更小的二级索引来进行统计。 如果有多个二级索引的时候,会使用key_len小的二级索引进行扫描。当没有二级索引的时候,才会采用主键索引来进行统计。 优化总结: 1、一般情况下:COUNT(*) = COUNT(1) > COUNT(字段) 所以尽量使用COUNT(*),当然如果你要统计的是就是某个字段的非空数据行数,那另当别论。毕竟执行效率比较的前提是要结果一样才行。 2、如果要统计COUNT(*),尽量在数据表上建立二级索引,系统会自动采用key_len小的二级索引进行扫描,这样当我们使用SELECT COUNT(*)的时候效率就会提升,有时候提升几倍甚至更高都是有可能的。

    2019-06-22
    4
    170
  • C先生丶陈
    置顶
    做一个搬运工,下面是从老师GitHub上找到的建表语句: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for heros -- ---------------------------- DROP TABLE IF EXISTS `heros`; CREATE TABLE `heros` ( `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `hp_max` float NULL DEFAULT NULL, `hp_growth` float NULL DEFAULT NULL, `hp_start` float NULL DEFAULT NULL, `mp_max` float NULL DEFAULT NULL, `mp_growth` float NULL DEFAULT NULL, `mp_start` float NULL DEFAULT NULL, `attack_max` float NULL DEFAULT NULL, `attack_growth` float NULL DEFAULT NULL, `attack_start` float NULL DEFAULT NULL, `defense_max` float NULL DEFAULT NULL, `defense_growth` float NULL DEFAULT NULL, `defense_start` float NULL DEFAULT NULL, `hp_5s_max` float NULL DEFAULT NULL, `hp_5s_growth` float NULL DEFAULT NULL, `hp_5s_start` float NULL DEFAULT NULL, `mp_5s_max` float NULL DEFAULT NULL, `mp_5s_growth` float NULL DEFAULT NULL, `mp_5s_start` float NULL DEFAULT NULL, `attack_speed_max` float NULL DEFAULT NULL, `attack_range` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `role_main` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `role_assist` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `birthdate` datetime(0) NULL DEFAULT NULL, PRIMARY KEY (`name`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

    作者回复: Good Share!

    2019-06-22
    4
    24
  • Shame
    先交作业 select name,mp_max from heros order by hp_max desc limit 5; 然后就是楼下一个同学问的问题,我也有些疑惑,就是这个 SELECT DISTINCT player_id, player_name, count(*) as num # 顺序 5 FROM player JOIN team ON player.team_id = team.team_id # 顺序 1 WHERE height > 1.80 # 顺序 2 GROUP BY player.team_id # 顺序 3 HAVING num > 2 # 顺序 4 ORDER BY num DESC # 顺序 6 LIMIT 2 # 顺序 7 对于这个语句,我还有一点疑问:既然HAVING的执行是在SELECT之前的,那么按理说在执行HAVING的时候SELECT中的count(*)应该还没有被计算出来才对啊,为什么在HAVING中就直接使用了num>2这个条件呢? 希望老师百忙之中能抽空帮忙解释一下,谢谢老师

    作者回复: 很好的问题,实际上在Step4和Step5之间,还有个聚集函数的计算。 如果加上这个计算过程,完整的顺序是: 1、FROM子句组装数据 2、WHERE子句进行条件筛选 3、GROUP BY分组 4、使用聚集函数进行计算; 5、HAVING筛选分组; 6、计算所有的表达式; 7、SELECT 的字段; 8、ORDER BY排序 9、LIMIT筛选 所以中间有两个过程是需要计算的:聚集函数 和 表达式。其余是关键字的执行顺序,如文章所示。

    2019-06-27
    8
    105
  • Samson
    老师,可以说下SELECT语句执行原理那个视例中HAVING关键字的作用嘛?

    作者回复: HAVING一般配合GROUP BY使用,作为筛选分组的条件。作用实际上和WHERE一样,都适用于限定条件。只是WHERE子句用于对查询结果的分组前,通过WHERE来过滤。而HAVING子句用于筛选满足条件的组,用于在分组之后进行过滤。这个我在后面也会讲到。

    2019-06-24
    22
  • ack
    老师好,请问能把建表的sql给出来吗?

    作者回复: 可以看下 https://github.com/cystanford/sql_heros_data

    2019-06-21
    6
    20
  • lincan
    老师讲得很棒,但有一处困惑:limit是最后执行的话,执行limit时全表扫描和所有的虚拟表都已生成了,那使用limit为什么还能提高效率呢?

    作者回复: 你可以通过 SHOW PROFILE 来查看 SQL 的具体执行成本,如果我们使用LIMIT进行限制,至少可以减少数据传输量,这样在Sending data这项上可以减少大量传输时间,而这一项又在整个SQL执行成本中占比比较高。

    2019-09-01
    4
    18
  • 时间是最真的答案
    MySQL SELECT `name`,mp_max FROM heros ORDER BY hp_max DESC LIMIT 5

    作者回复: 正确,同时也考虑到了给查询字段使用反引号

    2019-06-24
    4
    16
  • William
    前端开发第一次接触数据库。 1. 请问老师Mac上安装MySQL,安装8.0版本还是5.7版本更好? 2. 是否需要安装Navicat,PostgreSQL?

    作者回复: 建议安装最新的8.0版本,可以使用Navicat来管理MySQL。PostgreSQL是另一个RDBMS,先使用一种数据库即可,刚接触数据库,可以先从MySQL入手,当然SQL Server也是不错的选择。

    2019-07-11
    7
  • hlz-123
    数据库,MySQL8.0 SELECT name as '姓名',mp_max as '最大法力' FROM heros ORDER BY hp_max LIMIT 5;

    作者回复: 赞下用8.0的同学

    2019-06-23
    7
  • 业余草
    create table 还没学吧,我是小白,教一下 create table 或者 create table like。就单拿 select 说,这章内容也不全啊,group,having 等都漏掉了

    作者回复: GROUP, HAVING 在后面章节有

    2019-06-21
    2
    6
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部