Structured Query Language简称SQL,是一种操作数据库的语言。它包括数据库创建,删除,获取行,修改行等。SQL是结构化查询语言,它是一种用于存储,处理和检索关系数据库中存储的数据的计算机语言。
SQL是关系数据库系统的标准语言。所有关系数据库管理系统(RDMS),例如MySQL,MS Access,Oracle,Sybase,Informix,Postgres和SQL Server,都使用SQL作为其标准数据库语言。
git clone https://github.com/Samurais/sql-in-10-mins.git
源自:SQL 必知必会(第四版)
名称 | 含义 | 主要内容 |
---|---|---|
Cusmtosers | 顾客表 | 顾客ID、名字、地址、城市等 |
Orders | 订单表 | 订单ID、订单时间、关联的顾客ID |
OrderItems | 订单商品表 | 商品ID、质量、订单数量 |
Products | 商品表 | 商品价格、商品名称等 |
Vendors | 商品制造商表 | 制造商名字、地址、城市等 |
语句 | 含义 |
---|---|
create | 创建 |
rename | 重命名 |
alter | 增加列 |
drop | 删除 |
-- 创建表 ,可以指定默认值
create table Products2
(
prod_id char(10) NOT NULL ,
vend_id char(10) NOT NULL ,
prod_name char(255) NOT NULL ,
prod_price decimal(8,2) NOT NULL default 1.00,
prod_desc text NULL
);
-- 增加新字段
alter table Products2 add prod_type char(10) NOT NULL;
-- 重命名表
rename table Products2 to Products2Renamed;
-- 删除表
drop table Products2Renamed;
-- 复制表:
-- CREATE TABLE 新表 SELECT * FROM 旧表
语句 | 含义 |
---|---|
select | 从表中选取数据 |
order by | 排序 |
where | 过滤 |
like | 模糊匹配 |
function | 函数 |
--select
-- 检索单个列
select prod_name from Products;
-- 检索多个列
select prod_id , prod_name ,prod_price from Products;
-- 检索多个列
select * from Products;
-- 检索不同的值(返回互不相同的元素)
select DISTINCT vend_id from Products;
-- 检索前5行
select prod_name from Products LIMIT 5;
-- 检索从第6行开始的连续4行
select prod_name from Products LIMIT 4 OFFSET 5;
-- 或简写为:
select prod_name from Products LIMIT 4,5;
-- order by
-- 排序数据
select prod_name from Products order by prod_name;
-- 按多个列排序. 查找所有的商品Id,商品价格,商品名称。并按照价格排序,价格相同时,按名字排序
select prod_id,prod_price,prod_name from Products order by prod_price,prod_name;
-- 按多个列排序中也可以用数字代替(这里的数学是select中的位置),不建议这个做。意义不明确,可读性不好
select prod_id,prod_price ,prod_name from Products order by 2 ,3;
-- 降序排序(默认是升序),单列
select prod_id,prod_price ,prod_name from Products order by prod_price DESC;
-- 降序排序(默认是升序),多列(每列都要加上关键字)
select prod_id,prod_price ,prod_name from Products order by prod_price DESC, prod_name DESC;
-- where
--过滤
select prod_name,prod_price from Products where prod_price = 3.49;
-- 小于
select prod_name,prod_price from Products where prod_price<10;
-- 不等于
select prod_id ,vend_id from Products where vend_id <> 'DLL01';
select prod_id ,vend_id from Products where vend_id != 'DLL01';
-- between and
select prod_id,prod_price from Products where prod_price between 5 and 10;
--is null (这里是从customers表中查)
select cust_id,cust_email from Customers where cust_email IS NULL;
select cust_id,cust_email from Customers where cust_email is not NULL;
-- and or
-- and 查找所有供货商为DLL01的,并且价格低于4美元的产品
select prod_id,prod_name from Products where vend_id = 'DLL01'
and prod_price<=4;
-- or 查找所有供货商DLL01和BRS01供应的商品
select prod_id ,prod_name from Products where vend_id = 'DLL01' or vend_id = 'BRS01';
-- and or查找所有供货商DLL01和BRS01供应的,并且价格高于10美元的商品
select prod_id ,prod_name,prod_price from Products where (vend_id = 'DLL01' or vend_id = 'BRS01' ) and prod_price > 10;
-- IN 查找所有供货商DLL01和BRS01供应的商品
select prod_id ,vend_id from Products where vend_id in ('DLL01', 'BRS01');
-- NOT 查找除了供货商DLL01供应的商品外所有其他的商品
select prod_id ,vend_id from Products where NOT vend_id = 'DLL01';
-- 相当于
select prod_id ,vend_id from Products where vend_id != 'DLL01';
-- like
-- 寻找所有以 'FISH'开头的产品
select prod_name from Products where prod_name like 'FISH%';
-- 寻找中间字段为'bean bag'的
select prod_name from Products where prod_name like '%bean bag %';
-- _通配符只匹配一个字符
select prod_id ,prod_name from Products where prod_name like '_ inch teddy bear';
-- []匹配,相当于[J%]和[M%] mysql好像不支持
select cust_contact from Customers where cust_contact like '[JM]%';
-- function
-- 小写转大写函数 UPPER
select vend_name ,UPPER(vend_name) as vend_name_upcase from Vendors;
-- 查找2012年的所有订单,year也可以
select order_num from Orders where YEAR(order_date)=2012;
创建记录:用于向表格中插入新的行。
-- insert:在customers表中增加一行数据
insert into Customers(cust_id ,cust_name,cust_address, cust_city, cust_state,cust_zip)
values( concat(FLOOR(RAND() * 1000000000), ''), 'Toy Land','123 Any Steet','New York', 'NY', '11111');
更新记录:用于更新表中已存在的记录。
--update: 给100000005增加电子邮件
update Customers set cust_email='[email protected]' where cust_id = '1000000005';
-- 取消给100000005增加电子邮件
update Customers set cust_email=NULL where cust_id = '1000000005';
删除记录:用于删除表中的行。
-- delete 删除100000006这一行
delete from Customers where cust_id = '1000000006';
-- 求平均数 求Products表中所有商品的平均价格
select AVG(prod_price) as avg_price from Products;
-- 统计所有顾客数(即统计一共有多少行) 求Customers表中顾客数
select count(*) as num_cust from Customers;
-- 只统计有邮件的顾客数
select count(cust_email)as n_email_cust from Customers;
-- 求最贵的商品价格
select max(prod_price) as max_price from Products;
select min(prod_price) as min_price from Products;
-- 求订单20005所有购买的商品数
select sum(quantity) as item_ordered from OrderItems where order_num= 20005;
-- 注意下面这个,它实际上求的是订单20005中买了几种商品
select count(*) from OrderItems where order_num=20005;
-- 聚集不同值 求供货商DLL01供应的商品价格的平均值(同样的价格的只算一次)
select AVG(DISTINCT prod_price) as avg_price from Products where vend_id='DLL01';
-- 组合聚集 求所有的商品数,最大商品价格,最小商品价格,平均价格
select count(*),min(prod_price),max(prod_price),avg(prod_price) from Products;
-- 在上面的语句中,重点关注一下 select count(*) from Products; 这个是求所有的行数,也就是所有的商品数!
-- 请列出最低价的products是哪些?
-- 错误的写法 select prod_name ,prod_price from `Products` where prod_price=min(prod_price);
-- 正确的写法,使用子查询
select prod_name ,prod_price from `Products` where prod_price = (select min(prod_price) from `Products`);
拼接字符串:用于将两个字符串连接为一个字符串。
-- 拼接字符串 (mysql 不支持)
select CONCAT(vend_name,'(',vend_country, ')') from Vendors;
别名:为表名称或列名称指定别名。
-- 别名,将查询结果保存为vend_title名 as 。
select CONCAT(vend_name,'(',vend_country, ')') AS vend_titile from Vendors;
-- 别名
select prod_id ,quantity,item_price ,quantity*item_price as total_price from OrderItems where order_num = 20008;
聚集:表示根据by后面的字段进行分组。
-- 求各供应商供应的商品种类数(即 将Prodects以vend_id聚集)
select count(*) from Products group by vend_id;
-- 按 vend_id排序并分组数据
select vend_id,count(*) from Products group by vend_id;
-- Order表中求有两个及以上的订单的客户(having),将Orders以cust_id聚集
-- 使用Having过滤分组,该需求Where不能满足,Where作用于分组前,Having作用于分组后
select cust_id from Orders group by cust_id having count(*)>=2;
子查询:在多个表中查找,用到子查询,即一个select的结果作为另一个select的条件。
-- 1. 求订购了RGAN01这种商品的所有顾客。
-- 第一步,在OrderIterms表中求出购买了RGAN01的订单号
select order_num from OrderItems where prod_id='RGAN01';
-- 第二步,根据上面的订单号再在Orders表中求出对应的cust_id
select cust_id from Orders where (order_num='20007' or order_num='20008');
-- 可以把两句合成一句,即第一步的结果作为第二步的条件
select cust_id from Orders where order_num IN (select order_num from OrderItems where prod_id = 'RGAN01');
-- 2. 求Customers表中每个客户的订单总数
-- 需要注意的是,直接在orders表中根据cust_id来统计不正确,因为在Customers中的顾客只是orders表中cust_id的一部分。一个子集而已,所以这个是不完全正确的。
select cust_id ,count(*) from Orders group by cust_id;
-- 我们可以一个一个的求,但是数据量很大时就不方便!
select count(*) from Orders where Orders.cust_id = '1000000001';
-- 当然,我们一起求啊,
-- select count(*) from Orders where Orders.cust_id = Customers.cust_id;
-- 但是这个出错了!ERROR 1054 (42S22): Unknown column 'Customers.cust_id' in 'where clause'
-- 这个cust_id是多少呢?数据库它并不知道。所以我们还需要一个select cust_id from Customers来得到一个cust_id的list
-- 最终正确的. 这个不是很好的做法,更容易理解的见后面的join用法
select cust_name,(select count(*) from Orders where Orders.cust_id = Customers.cust_id) from Customers;
连接:用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
-- 1. 求订购了RGAN01这种商品的所有顾客。
-- 这里的order_num就是连接的字段
-- 然后OrderIterms表中的prod_id就是在另一侧的表中进行筛选
select cust_id from Orders ,OrderItems where Orders.order_num=OrderItems.order_num and OrderItems.prod_id = 'RGAN01';
-- 2. 求Customers表中每个客户的订单总数
select cust_name ,count(*) from Orders,Customers where Orders.cust_id = Customers.cust_id group by Customers.cust_id;
-- 1.自连接
-- 使用自连接的方法,实际上只不过是在一张表中了。但是你把它看做两张表即可。
select Customers.cust_name from Customers where Customers.cust_name = Customers.cust_name and Customers.cust_contact ='Jim Jones';
-- 2. 外连接
-- 检索custoerms表中所有顾客及其订单
-- 使用内连接(检索结果不正确,为空的检索不出来)
select Customers.cust_id ,Orders.order_num from Customers,Orders where Orders.cust_id=Customers.cust_id;
-- 交换 ‘=’ 两边的值也没有效果
select Customers.cust_id ,Orders.order_num from Customers,Orders where Customers.cust_id = Orders.cust_id;
-- 外左连接(结果正确!他是以custoerms表为标准,交换'='两边无所谓,主要是看Customers LEFT OUTER JOIN Orders这里有个记忆方法,出现left的就以左边的表为表中,出现right的就右边。)
select Customers.cust_id ,Orders.order_num from Customers LEFT OUTER JOIN Orders ON Orders.cust_id=Customers.cust_id;
-- 外右连接(检索结果不正确,为空的检索不出来,因为它是以右边的Order为标准
select Customers.cust_id ,Orders.order_num from Customers RIGHT OUTER JOIN Orders ON Orders.cust_id=Customers.cust_id;
-- 3.全连接
-- 全连接相当于left和right的总和(mysql不支持)
-- MySQL本身不支持full join(全连接),但可以通过union来实现
-- 4.连接与聚集函数的结合
-- 要检索所有每个顾客下的订单数
-- 这个使用的是内连接,不统计空的
select cust_name ,count(*) from Orders,Customers where Orders.cust_id = Customers.cust_id group by Customers.cust_id;
-- 外连,统计空的
-- 查看RIGHT JOIN得到了什么
select * from Orders RIGHT JOIN Customers ON Orders.cust_id = Customers.cust_id ;
-- 要检索所有每个顾客下的订单数,支持空的
select cust_name,Orders.cust_id,count(Orders.cust_id) from Orders RIGHT JOIN Customers ON Orders.cust_id = Customers.cust_id GROUP BY Orders.cust_id ;
合并:将多条select语句组合成一个结果集。
-- 例子: 现需要查询llinois、Indiana、和Michigan等美国几个州的所有顾客的名字,
-- 还想知道不管位于哪个州的所有Fun4ALL顾客的名字。
-- 用union实现
select cust_contact from Customers where cust_state IN('MI','IN','IL') union select cust_name from Customers where cust_name = 'Fun4All';
视图:视图是基于SQL 语句的结果集的可视化的表。
--求订购了RGAN01的所有顾客id
-- 视图,简化查询。
-- 它是一个查询,并不包含具体的表的数据,也叫虚表
-- 它返回的是订购了任意产品的顾客。
create view ProductCustomers as select cust_id,prod_id from Orders ,OrderItems where Orders.order_num=OrderItems.order_num;
-- 查找购买了RGAN01的顾客id
select cust_id from ProductCustomers where prod_id = 'RGAN01';
存储过程:是一组为了完成特定功能的SQL语句集
-- 1.创建存储过程(函数),计算两个数的和
-- ----------------------------
-- Procedure structure for `proc_adder`
-- ----------------------------
DROP PROCEDURE IF EXISTS proc_adder;
DELIMITER ;;
CREATE PROCEDURE proc_adder (IN a int, IN b int, OUT sum int)
BEGIN
-- Routine body goes here...
DECLARE c int;
if a is null then
set a = 0;
end if;
if b is null then
set b = 0;
end if;
set sum = a + b;
END;;
DELIMITER ;
-- 调用
set @b=5;
call proc_adder(2,@b,@num);
SELECT @num;
MySQL的运维工具很多,使用这些工具使得工作更加轻松。例如:
春松客服部署方案
春松客服数据词典
春松客服开发环境
春松客服是 Chatopera 自主研发的,Apache2.0开源协议授权的智能客服系统,春松客服会不断增强客服系统的智能化,这包括利用自然语言处理、机器学习和语音识别等技术让客服工作更有效率、客服满意度更高、成本更低。