美文网首页
SQL基础教程(1)

SQL基础教程(1)

作者: leejnull | 来源:发表于2020-01-08 22:35 被阅读0次

以下基于mysql

一个商品表

create table Product (
product_id char(4) not null,
product_name varchar(100) not null,
product_type varchar(32) not null,
sale_price integer ,
purchase_price integer ,
regist_date date ,
primary key (product_id));

导入sql语句

// 进入mysql命令行
source 路径

删除表

drop table product

重命名表

rename table Poduct to Product

增加列

alter table product add column product_name_pinyin varchar(100);

删除列

alter table product drop column product_name_pinyin;

更改列为主键

alter table product add primary key (product_id);

插入行

begin transaction;
INSERT INTO Product VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2019-12-30');
INSERT INTO Product VALUES ('0002', '打孔器', '办公用品', 500, 320, '2019-12-29');
INSERT INTO Product VALUES ('0003', '运动T恤','衣服', 4000, 2800, NULL);
INSERT INTO Product VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2019-12-28');
INSERT INTO Product VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2019-12-27');
INSERT INTO Product VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2019-12-26');
INSERT INTO Product VALUES ('0007', '擦菜板', '厨房用具', 880, 790, '2019-12-25');
INSERT INTO Product VALUES ('0008', '圆珠笔', '办公用品', 100, NULL, '2019-12-24');
commit;

SELECT

查询列设置别名
select product_id as id, product_name as name, purchase_price as price from product;

select product_id as "商品编号", product_name as "商品名称", purchase_price as "进货单价" from product;

设置汉语要用双引号""

设置常数显示
select '商品' as string, 38 as number, '2019-02-24' as date, product_id, product_name from product;

显示结果每一行都会有 商品,38,2019-02-24这三个数据

从结果中删除重复行
select distinct product_type from product;

select distinct product_type, regist_date from product;

如果有NULL,会被当成一类来显示

where
select product_name, product_type from product where product_type='衣服';

select product_name from product where product_type = '衣服';
注释
-- 单行注释

/* 多行注释
*/

算数运算符

  • +
  • -
  • *
  • /
select product_name, sale_price, sale_price * 2 as "sale_price_x2" from product;

比较运算符

-- 等于
select product_name, product_type from product where sale_price = 500;
-- 不等于
select product_name, product_type from product where sale_price <> 500;
/*
还有
>=
>
<=
<
*/

联合使用

select product_name, sale_price, purchase_price from product where sale_price - purchase_price >= 500;

NULL不能比较,只能用 is null & is not null 来判断

select product_name, purchase_price from product where purchase_price is null;

逻辑运算符

not
select product_name, product_type, sale_price from product where not sale_price >= 1000;
and & or
select product_name, purchase_price from product where product_type='厨房用具' and sale_price >= 3000;

select product_name, purchase_price from product where product_type='厨房用具' or sale_price >= 3000;

select product_name, product_type, regist_date from product where product_type='办公用品' and (regist_date = '2019-12-29' or regist_date = '2019-12-24');

and运算符优先级高于or,所以要加上括号

聚合与排序

对表进行聚合查询
  • COUNT: 计算表中的记录数(行数)
  • SUM: 计算表中数值列中数据的合计值
  • AVG: 计算表中数值列中数据的平均值
  • MAX: 求出表中任意列中数据的最大值
  • MIN: 求出表中任意列中数据的最小值
  • DISTINCT: 删除重复值
-- 计算行数
select count(*) from product;
-- count(*)会得到包含NULL的数据行数,count(列名)会得到NULL之外的数据行数

-- 计算合计值
select sum(sale_price) from product;

-- 计算平均值
select avg(sale_price) from product;
-- avg自动把NULL排除,所以这时候数量是6

-- 最大值,最小值
select max(sale_price), min(purchase_price) from product;
-- min和max理论上适用于任何数据类型的列,字符串、日期等的比较也不会有问题,但是SUM/AVG不行

-- 计算删除重复数据后的数据行数
select count(distinct product_type) from product;
-- 所有的聚合函数都可以使用distinct

所有包含列名的聚合函数,都会把NULL排除在外

对表进行分组

先把表分成几组,在进行汇总处理

GROUP BY
-- 将数据按照product_type分类,并计算每个分类的数量
select product_type, count(*) from product group by product_type;

select purchase_price, count(*) from product where product_type='衣服' group by purchase_price;
  1. 如果有group by,那么select语句只能使用group by指定的列名
  2. group by 不能使用 select 中列的别名
  3. group by 字句结果的显示是无序的
  4. 只有 select, having, order by 字句中能够使用聚合函数
为聚合结果指定条件
  • 使用COUNT函数等对表中数据进行汇总操作时,为其指定条件的不是where字句,而是HAVING字句
  • 聚合函数可以在SELECT字句、HAVING字句和ORDER BY字句中使用
  • HAVING字句要写在GROUP BY字句之后
  • WHERE字句用来指定数据行的条件,HAVING字句用来指定分组的条件
-- 按照商品种类进行分组后的结果中,取出”包含的数据行数为2行的组“
select product_type, count(*) from product group by product_type having count(*) = 2;
-- 取出销售单价大于等于2500的分组数据
select product_type, avg(sale_price) from product group by product_type having avg(sale_price) >= 2500;

聚合键所对应的条件不应该卸载HAVING字句当中,而应该书写在WHERE字句当中

对查询结果进行排序
select product_id, product_name, sale_price, purchase_price from product order by sale_price;

select product_id, product_name, sale_price, purchase_price from product order by sale_price DESC;

-- order by 字句中可以使用列的别名
select product_id as id, product_name, sale_price as sp, purchase_price from product order by sp, id;

-- select字句中未包含的列也可以在order by字句中使用
select product_name, sale_price, purchase_price from product order by product_id;
-- 在order by字句中可以使用select字句中未使用的列和聚合函数
select product_type, count(*) from product group by product_type order by count(*);

未指定ORDER BY字句中排列顺序时会默认使用升序进行排列
排序键中包含NULL时,会在开头或末尾进行汇总

为什么order by可以使用别名,group by不可以呢?

这里要知道使用HAVING字句时SELECT语句的顺序

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

SELECT字句的执行顺序是在GROUP BY字句之后,ORDER BY字句之前,因此在执行GROUP BY字句时,SELECT语句中定义的别名无法被识别

数据更新

数据的插入
-- 通常的insert
insert into ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) values ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
-- 多行insert
insert into ProductIns values ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'), ('0003', '运动T恤', '衣服', 4000, 2800, NULL), ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
-- 省略列清单
insert into ProductIns values ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
-- 插入NULL
insert into ProductIns (product_id, product_name, product_type, sale_price, purchase, regist_date) values ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
-- 插入默认值(显式方式)
insert into ProductIns (product_id, product_name, product_type, sale_price, purchase, regist_date) values ('0007', '擦菜板', '厨房用具', DEFAULT, 790, '2009-04-28');
-- 插入默认值(隐式方式)
insert into ProductIns (product_id, product_name, product_type, purchase, regist_date) values ('0007', '擦菜板', '厨房用具', 790, '2009-04-28');

-- 使用显式方式更容易理解
从其他表中复制数据
insert into ProductCopy (product_id, product_name, product_type, sale_price, purchase_price, regist_date) select product_id, product_name, product_type, sale_price, purchase_price, regist_date from Product;

-- 多种多样的select
insert into ProductType (product_type, sum_sale_price, sum_purchase_price) select product_type, sum(sale_price), sum(purchase_price) from Product group by product_type;
数据的删除

drop table 删除整个表,delete 删除表中的数据

-- 清空表
delete from ProductType;
-- 根据条件删除
delete from Product where sale_price >= 4000;

delete只能使用where字句,group by、having、order by不能用,没有意义

truncate与delete相似,但是前者只能删除表中的全部数据,而不能通过where字句指定条件来删除部分数据,因为它只能删除全部,所以处理速度别delete更快

数据的更新

update

update Product set regist_date='2009-10-10';

-- 指定条件
update Product set sale_price = sale_price * 10 where product_type='厨房用具';

-- 使用NULL进行更新
update Product set regist_date = NULL where product_id='0008';

-- 多列更新
update Product set sale_price = sale_price * 10, purchase_price = purchase_price / 2 where product_type = '厨房用具';
事务
  • 事务是需要在同一个处理单元中执行的一系列更新处理的集合。通过使用事务,可以对数据库中的数据更新处理的提交和取消进行管理
  • 事务处理的终止指令包括COMMIt(提交处理)和ROLLBACK(取消处理)两种
  • DBMS的事务具有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)四种特性,统称为ACID特性

事务是需要在同一个处理单元中执行的一系列更新处理的集合

start transaction;

update Product set sale_price = sale_price+1000 where product_id='0001';

commit;

-- rollback 回滚到开始事务之前的状态

当开启一个连接对数据库进行操作时,启动事务,修改,还没有提交,此时启动另一个连接,是看不到还没有提交的事务修改后的数据的。这时候如果执行 delete 操作,就会阻塞住,只有等之前的事务提交后才会继续执行delete

复杂查询

视图

视图并不保存数据,它保存的是select语句

create view ProductSum (product_type, cnt_product) as select product_type, count(*) from product group by product_type;

select product_type, cnt_product from ProductSum;

drop view ProductSum;

从视图中查找就是调用视图的select语句

视图支持嵌套,但不建议,影响性能

从表中更新数据,查询视图也会同步更新,因为本质是select。从视图更新数据,也会影响到表,但是有限制

  • SELECT子句中未使用DISTINCT
  • FROM字句中只有一张表
  • 未使用GROUP BY子句
  • 未使用HAVING子句
子查询

一张一次性视图

select product_type, cnt_product from (select product_type, count(*) as cnt_product from Product group by product_type) as ProductSum;

-- 就是将用来定义视图的select语句直接用于from字句当中,as ProductSum就是子查询的名称,但是是一次性的,执行完之后就消失

子查询作为内存查询会首先执行,且没有层数上的限制

标量子查询

只能返回表中某一行的某一列的值

-- 找出售价高于平均售价的产品
select product_id, product_name, sale_price from Product where sale_price > avg(sale_price);

-- 很明显上面是错误的写法,where字句不能有聚合函数,所以这里就要用到标量子查询
select product_id, product_name, sale_price from Product where sale_price > (select avg(sale_price) from Product);

标量子查询的书写位置不局限于where字句中,通常任何可以使用单一值的位置都可以使用

-- select子句使用标量子查询
select product_id, product_name, sale_price, (select avg(sale_price) from Product) as avg_price from Product;

-- having子句使用标量子查询
select product_type, avg(sale_price) from Product group by product_type having avg(sale_price) > (select avg(sale_price) from Product);

注意:标量子查询的结果一定不能返回多行

关联子查询

如果要找出产品售价高于每个商品种类的平均售价的产品,理论上

select product_id, product_name, sale_price from Product where sale_price > (select avg(sale_price) from Product group by product_type);

这里用了标量子查询,但是是错误的,标量子查询的返回结果必须是单一值,这里返回了多个值(每个商品种类的平均售价),比较是不成立的

用关联子查询来解决

select product_id, product_name, sale_price from Product as P1 where sale_price > (select avg(sale_price) from Product as P2 where P1.product_type = P2.product_type group by product_type);

关联子查询相比于标量子查询增加了一个判断,用来找出子查询返回多个结果的相匹配的那一个,这样就可以用来比较了,要注意关联名称的范围

来自 https://leejnull.github.io/2020/01/08/2020-01-08-01/

相关文章

  • SQL基础教程-1章1节:数据库结构和SQL书写规则

    视频教程地址:SQL基础教程-1章1节:数据库结构和SQL书写规则_哔哩哔哩_bilibili[https://w...

  • MySQL一一sql基本语法

    sql基础教程 sql教程 什么是sql? SQL 指结构化查询语言 SQL 使我们有能力访问数据库 SQL 是一...

  • SQL基础

    SQL基础教程。 注意: SQL 对大小写不敏感! SQL DML 和 DDL 可以把 SQL 分为两个部分:数据...

  • SQL基础<一>

    前言 计划 传送门:SQL基础教程 数据库和SQL 1.数据库 提到SQL,首先必须谈到数据库,那么什么是数据库?...

  • 1 SQL基础教程

    1 SQL基础 1.1 SQL 简介 SQL(结构化查询语言)是用于访问和操作数据库中的数据的标准数据库编程语言。...

  • SQL基础教程(1)

    以下基于mysql 一个商品表 导入sql语句 删除表 重命名表 增加列 删除列 更改列为主键 插入行 SELEC...

  • SQL基础教程:搭建SQL开发环境

    视频教程地址:SQL基础教程:搭建SQL开发环境_哔哩哔哩_bilibili[https://www.bilibi...

  • SQL基础教程(第二版)学习笔记

    SQL基础教程(第二版) 1 数据库和SQL 1.1 数据库管理系统 DBMS** 层次数据库 HDB 关系数据库...

  • SQL 学习笔记

    《SQL 基础教程》学习笔记 01 - 数据库和 SQL 02 - 表的创建、删除和更新 03 - 查询基础 04...

  • PL_SQL_Oracle基础教程.pdf

    【下载地址】 PL /SQL基础教程-PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL...

网友评论

      本文标题:SQL基础教程(1)

      本文链接:https://www.haomeiwen.com/subject/agreactx.html