MySQL篇五:基本查询

打印 上一主题 下一主题

主题 1875|帖子 1875|积分 5625

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前言

  表的增编削查:CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)。
1. Create

  语法:
  1. INSERT [INTO] table_name
  2.         [(column [, column] ...)]
  3.         VALUES (value_list) [, (value_list)] ...
  4. value_list: value, [, value] ...
复制代码
  样例:
  1. CREATE TABLE students (
  2.         id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  3.         sn INT NOT NULL UNIQUE COMMENT '学号',
  4.         name VARCHAR(20) NOT NULL,
  5.         qq VARCHAR(20)
  6. );
复制代码
1.1 单行数据 + 全列插入

  1. INSERT INTO students VALUES (100, 10000, '唐三藏', NULL);
复制代码
1.2 多行数据 + 指定列插入

  1. INSERT INTO students (id, sn, name) VALUES
  2. (102, 20001, '曹孟德'),
  3. (103, 20002, '孙仲谋');
复制代码
1.3 插入否则更新

  如果插入的数据发生冲突,则进行修正。
  可以选择性的进行同步更新操作 语法:
  1. INSERT ... ON DUPLICATE KEY UPDATE
  2.         column = value [, column = value] ...
复制代码
  样例:
  1. INSERT INTO students (id, sn, name) VALUES (100, 10010, '唐大师')
  2.         ON DUPLICATE KEY UPDATE sn = 10010, name = '唐大师';
复制代码
  解释:如果(100, 10010, ‘唐大家’)发生数据冲突,则将已插入的值修改为 sn = 10010, name = ‘唐大家’。好比说此时数据库中有(100, 9999, ‘唐玄奘’),由于id是主键,新插入数据的id发生了冲突,那么就会将(100, 9999, ‘唐玄奘’)改为(100, 10010, ‘唐大家’)。
  1. SELECT ROW_COUNT();  //通过 MySQL 函数获取受到影响的数据行数
复制代码
1.4 替换

  1. -- 主键 或者 唯一键 没有冲突,则直接插入;
  2. -- 主键 或者 唯一键 如果冲突,则删除后再插入
  3. REPLACE INTO students (sn, name) VALUES (20001, '曹阿瞒');
  4.         Query OK, 2 rows affected (0.00 sec)
复制代码
2. Retrieve

  语法:
  1. SELECT
  2.         [DISTINCT] {* | {column [, column] ...}
  3.         [FROM table_name]
  4.         [WHERE ...]
  5.         [ORDER BY column [ASC | DESC], ...]
  6.         LIMIT ...
复制代码
  样例:
  1. -- 创建表结构
  2. CREATE TABLE exam_result (
  3.         id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  4.         name VARCHAR(20) NOT NULL COMMENT '同学姓名',
  5.         chinese float DEFAULT 0.0 COMMENT '语文成绩',
  6.         math float DEFAULT 0.0 COMMENT '数学成绩',
  7.         english float DEFAULT 0.0 COMMENT '英语成绩'
  8. );
复制代码
2.1 SELECT 列

2.1.1 全列查询

  1. -- 通常情况下不建议使用 * 进行全列查询
  2. -- 1. 查询的列越多,意味着需要传输的数据量越大;
  3. -- 2. 可能会影响到索引的使用。(索引待后面讲解)
  4. SELECT * FROM exam_result;
复制代码
2.1.2 指定列查询

  1. -- 指定列的顺序不需要按定义表的顺序来
  2. SELECT id, name, english FROM exam_result;
复制代码
2.1.3 查询字段为表达式

  1. -- 表达式不包含字段
  2. SELECT id, name, 10 FROM exam_result;
复制代码
  1. -- 表达式包含一个字段
  2. SELECT id, name, english + 10 FROM exam_result;
复制代码
  1. -- 表达式包含多个字段
  2. SELECT id, name, chinese + math + english FROM exam_result;
复制代码
2.1.4 为查询结果指定别名

  语法:
  1. SELECT column [AS] alias_name [...] FROM table_name;
复制代码
  样例:
  1. SELECT id, name, chinese + math + english 总分 FROM exam_result;
复制代码
2.1.5 结果去重

  1. -- 98 分重复了
  2. SELECT math FROM exam_result;
复制代码
  1. -- 去重结果
  2. SELECT DISTINCT math FROM exam_result;
复制代码
2.2 WHERE 条件

  比较运算符:
运算符阐明>, >=, <, <=大于,大于等于,小于,小于等于=等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL<=>等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)!=, <>不等于BETWEEN a0 AND a1范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)IN (option, …)如果是 option 中的恣意一个,返回 TRUE(1)IS NULL是 NULLIS NOT NULL不是 NULLLIKE模糊匹配。% 体现恣意多个(包括 0 个)恣意字符;_ 体现恣意一个字符   逻辑运算符:
运算符阐明AND多个条件必须都为 TRUE(1),结果才是 TRUE(1)OR恣意一个条件为 TRUE(1), 结果为 TRUE(1)NOT条件为 TRUE(1),结果为 FALSE(0) 2.2.1 练习

  英语不合格的同砚及英语成绩 ( < 60 )
  1. -- 基本比较
  2. SELECT name, english FROM exam_result WHERE english < 60;
复制代码
  语文成绩在 [80, 90] 分的同砚及语文成绩
  1. -- 使用 AND 进行条件连接
  2. SELECT name, chinese FROM exam_result WHERE chinese >= 80 AND chinese <= 90;
复制代码
  1. -- 使用 BETWEEN ... AND ... 条件
  2. SELECT name, chinese FROM exam_result WHERE chinese BETWEEN 80 AND 90;
复制代码
  数学成绩是 58 大概 59 大概 98 大概 99 分的同砚及数学成绩
  1. -- 使用 OR 进行条件连接
  2. SELECT name, math FROM exam_result
  3.         WHERE math = 58
  4.         OR math = 59
  5.         OR math = 98
  6.         OR math = 99;
复制代码
  1. -- 使用 IN 条件
  2. SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);
复制代码
  姓孙的同砚及孙某同砚
  1. -- % 匹配任意多个(包括 0 个)任意字符
  2. SELECT name FROM exam_result WHERE name LIKE '孙%';
复制代码
  1. -- _ 匹配严格的一个任意字符
  2. SELECT name FROM exam_result WHERE name LIKE '孙_';
复制代码
  语文成绩好于英语成绩的同砚
  1. -- WHERE 条件中比较运算符两侧都是字段
  2. SELECT name, chinese, english FROM exam_result WHERE chinese > english;
复制代码
  总分在 200 分以下的同砚
  1. -- WHERE 条件中使用表达式
  2. -- 别名不能用在 WHERE 条件中
  3. SELECT name, chinese + math + english 总分 FROM exam_result
  4. WHERE chinese + math + english < 200;
复制代码
  语文成绩 > 80 并且不姓孙的同砚
  1. -- AND 与 NOT 的使用
  2. SELECT name, chinese FROM exam_result
  3.         WHERE chinese > 80 AND name NOT LIKE '孙%';
复制代码
  孙某同砚,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
  1. -- 综合性查询
  2. SELECT name, chinese, math, english, chinese + math + english 总分
  3. FROM exam_result
  4. WHERE name LIKE '孙_' OR (
  5.         chinese + math + english > 200 AND chinese < math AND english > 80
  6. );
复制代码
  NULL 的查询
  1. -- 查询 qq 号已知的同学姓名
  2. SELECT name, qq FROM students WHERE qq IS NOT NULL;
复制代码
  1. -- NULL 和 NULL 的比较,= 和 <=> 的区别
  2. SELECT NULL = NULL, NULL = 1, NULL = 0;
  3. +-------------+----------+----------+
  4. | NULL = NULL | NULL = 1 | NULL = 0 |
  5. +-------------+----------+----------+
  6. | NULL                   | NULL     | NULL     |
  7. +-------------+----------+----------+
复制代码
  1. SELECT NULL <=> NULL, NULL <=> 1, NULL <=> 0;
  2. +---------------+------------+------------+
  3. | NULL <=> NULL | NULL <=> 1 | NULL <=> 0 |
  4. +---------------+------------+------------+
  5. | 1             | 0          | 0          |
  6. +---------------+------------+------------+
复制代码
  如果使用=让null和其他值进行比较,结果都是null。如果使用<=>让null进行比较,只有 NULL <=> NULL的结果为1(真),其他都为0(假),由于null和0是不一样的。
2.3 结果排序

  语法:
  1. -- ASC 为升序(从小到大)
  2. -- DESC 为降序(从大到小)
  3. -- 默认为 ASC
  4. SELECT ... FROM table_name [WHERE ...]
  5.         ORDER BY column [ASC|DESC], [...];
复制代码
注意:没有 ORDER BY 子句的查询,返回的顺序是未定义的,永久不要依赖这个顺序。
2.3.1 练习

  同砚及数学成绩,按数学成绩升序显示
  1. SELECT name, math FROM exam_result ORDER BY math;
复制代码
  同砚及 qq 号,按 qq 号排序显示
  1. -- NULL 视为比任何值都小,升序出现在最上面
  2. SELECT name, qq FROM students ORDER BY qq;
复制代码
  1. -- NULL 视为比任何值都小,降序出现在最下面
  2. SELECT name, qq FROM students ORDER BY qq DESC;
复制代码
  查询同砚各门成绩,依次按 数学降序,英语升序,语文升序的方式显示
  1. -- 多字段排序,排序优先级随书写顺序
  2. SELECT name, math, english, chinese FROM exam_result
  3.         ORDER BY math DESC, english, chinese;
复制代码
  查询同砚及总分,由高到低
  1. SELECT name, chinese + english + math FROM exam_result
  2.         ORDER BY chinese + english + math DESC;
复制代码
  1. -- ORDER BY 子句中可以使用列别名
  2. SELECT name, chinese + english + math 总分 FROM exam_result
  3.         ORDER BY 总分 DESC;
复制代码
  查询姓孙的同砚大概姓曹的同砚数学成绩,结果按数学成绩由高到低显示
  1. -- 结合 WHERE 子句 和 ORDER BY 子句
  2. SELECT name, math FROM exam_result
  3.         WHERE name LIKE '孙%' OR name LIKE '曹%'
  4.         ORDER BY math DESC;
复制代码
  1. -- 错的,在where后面不允许使用别名
  2. select chinese+math as total from exam_result where total > 150;
  3. select chinese+math as total from exam_result where chinese+math > 150;
  4. -- 正确的,order by 后面可以使用别名,为什么呢?
  5. select chinese+math as total from exam_result order by total asc;
复制代码
2.4 筛选分页结果

  语法:
  1. -- 起始下标为 0
  2. -- 从 s 开始,筛选 n 条结果
  3. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n
  4. -- 从 0 开始,筛选 n 条结果
  5. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n;
  6. ;
  7. -- 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
  8. SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
复制代码
  发起:对未知表进行查询时,最好加一条 LIMIT 1,制止由于表中数据过大,查询全表数据导致数据库卡死,按 id 进行分页,每页 3 条记载,分别显示 第 1、2、3 页
  1. -- 第 1 页
  2. SELECT id, name, math, english, chinese FROM exam_result
  3.         ORDER BY id LIMIT 3 OFFSET 0;
复制代码
  1. -- 第 2 页
  2. SELECT id, name, math, english, chinese FROM exam_result
  3.         ORDER BY id LIMIT 3 OFFSET 3;
复制代码
  1. -- 第 3 页,如果结果不足 3 个,不会有影响
  2. SELECT id, name, math, english, chinese FROM exam_result
  3.         ORDER BY id LIMIT 3 OFFSET 6;
复制代码
3. Update

  语法:
  1. UPDATE table_name SET column = expr [, column = expr ...]
  2.         [WHERE ...] [ORDER BY ...] [LIMIT ...]
复制代码
3.1 练习

  将孙悟空同砚的数学成绩变更为 80 分
  1. UPDATE exam_result SET math = 80 WHERE name = '孙悟空';
复制代码
  将曹孟德同砚的数学成绩变更为 60 分,语文成绩变更为 70 分
  1. UPDATE exam_result SET math = 60, chinese = 70 WHERE name = '曹孟德';
复制代码
  将总成绩倒数前三的 3 位同砚的数学成绩加上 30 分
  1. -- 数据更新,不支持 math += 30 这种语法
  2. UPDATE exam_result SET math = math + 30
  3.         ORDER BY chinese + math + english LIMIT 3;
  4. -- 思考:这里还可以按总分升序排序取前 3 个么?
  5. SELECT name, math, chinese + math + english 总分 FROM exam_result
  6.         ORDER BY 总分 LIMIT 3;
复制代码
  将所有同砚的语文成绩更新为原来的 2 倍
  1. UPDATE exam_result SET chinese = chinese * 2;
复制代码
4. Delete

  语法:
  1. DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]
复制代码
4.1 练习

   删除孙悟空同砚的测验成绩
  1. DELETE FROM exam_result WHERE name = '孙悟空';
复制代码
  删除整张表数据
  1. DELETE FROM for_delete;
复制代码
  清除表数据,auto_increment并不会变为0,仍旧是清楚前的大小。截断表会清除auto_increment。
4.2 截断表

  语法:
  1. TRUNCATE [TABLE] table_name
复制代码
  注意:这个操作慎用

  • 只能对整表操作,不能像 DELETE 一样针对部分数据操作;
  • 实际上 MySQL 不对数据操作,以是比 DELETE 更快,但是TRUNCATE在删除数据的时候,并不经过真正的事物,以是无法回滚
  • 会重置 AUTO_INCREMENT 项
  1. -- 截断整表数据,注意影响行数是 0,所以实际上没有对数据真正操作
  2. TRUNCATE for_truncate;
复制代码
5. 插入查询结果

  语法:
  1. INSERT INTO table_name [(column [, column ...])] SELECT ...
复制代码
  1. -- 将 duplicate_table 的去重数据插入到 no_duplicate_table
  2. INSERT INTO no_duplicate_table SELECT DISTINCT * FROM duplicate_table;
  3. -- 通过重命名表,实现原子的去重操作
  4. RENAME TABLE duplicate_table TO old_duplicate_table,
  5. no_duplicate_table TO duplicate_table;
复制代码
6. 聚合函数

函数阐明COUNT([DISTINCT] expr)返回查询到的数据的数量SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义AVG([DISTINCT] expr)返回查询到的数据的 均匀值,不是数字没有意义MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义 6.1 练习

  统计班级共有多少同砚
  1. -- 使用 * 做统计,不受 NULL 影响
  2. SELECT COUNT(*) FROM students;
  3. -- 使用表达式做统计
  4. SELECT COUNT(1) FROM students;
复制代码
  统计班级收集的 qq 号有多少
  1. -- NULL 不会计入结果
  2. SELECT COUNT(qq) FROM students;
复制代码
  统计本次测验的数学成绩分数个数
  1. -- COUNT(math) 统计的是全部成绩
  2. SELECT COUNT(math) FROM exam_result;
  3. -- COUNT(DISTINCT math) 统计的是去重成绩数量
  4. SELECT COUNT(DISTINCT math) FROM exam_result;
复制代码
  统计数学成绩总分
  1. SELECT SUM(math) FROM exam_result;
  2. -- 不及格 < 60 的总分,没有结果,返回 NULL
  3. SELECT SUM(math) FROM exam_result WHERE math < 60;
复制代码
  统计均匀总分
  1. SELECT AVG(chinese + math + english) 平均总分 FROM exam_result;
复制代码
  返回英语最高分
  1. SELECT MAX(english) FROM exam_result;
复制代码
  返回 > 70 分以上的数学最低分
  1. SELECT MIN(math) FROM exam_result WHERE math > 70;
复制代码
7. group by子句的使用

  分组,聚合统计
  在select中使用group by 子句可以对指定列进行分组查询:
  1. select column1, column2, .. from table group by column;
复制代码
样例:
  准备工作,创建一个雇员信息表(来自oracle 9i的经典测试表)


  • EMP员工表
  • DEPT部分表
  • SALGRADE工资品级表
  group by —— 指定列名,实际分组,是用该列的差别行的数据来进行分组。分组的条件depton(下面的第一个例子),组内肯定是相同的,是可以被聚合压缩的。
  分组,就是把一组按照条件拆分成了多个组,进行各自组内的统计。分组(“分表”),就是把一长表按照条件在逻辑上拆成了多个元素,然后分别对各自的子表进行聚合统计。
7.1 练习

  怎样显示每个部分的均匀工资和最高工资
  1. select deptno,avg(sal),max(sal) from EMP group by deptno;
复制代码
  显示每个部分的每种岗位的均匀工资和最低工资
  1. select avg(sal),min(sal),job, deptno from EMP group by deptno, job;
复制代码
  只有分组之后的信息才能卸载select反面,在上面也就是只有depton和job可以写在select反面。
  显示均匀工资低于2000的部分和它的均匀工资
  1. 统计各个部分的均匀工资
  1. select avg(sal) from EMP group by deptno
复制代码
  2. having和group by共同使用,对group by结果进行过滤
  1. select avg(sal) as myavg from EMP group by deptno having myavg<2000;
  2. --having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where
复制代码
  having 和 where区别明白?实行顺序,构建对 “结果” 的明白。
  where是对具体的一列进行筛选,having是对分组聚合后的结果进行筛选。条件筛选的阶段是差别的。
  不要单纯的以为,只有磁盘上的表结构导入到MySQL,真实存在的表,才叫做表。在MySQL中心筛选出来的表,包括最终的结果,在我看来都是逻辑上的表。
面试题:SQL查询中各个关键字的实行先后顺序 from > on> join > where > group by > with > having > select> distinct > order by > limit

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表