本文参考文献为: 《SQL基础教程》MICK 著,孙淼 罗勇 译.
这是根据以上参考文献 第一章到第四章的总结。
-- summary_SQL基础教程MICK_chapter1to4
/*
#DDL(Data Definition Language)
#CREATE : create databases and tables;
#DROP : delete databases and tables;
#ALTER : modify tablebases and tables;
#DML(Data Manipulation Language)
#SELECT :
#INSERT :
#UPDATE :
#DELETE :
#DCL(Data Control Language)
#COMMIT :
#ROLLBACK:
#GRANT :
#REVOKE :
*/
/*
#----------------------------------------ops for database-----------------------------------#
#syntax:
# 1. create database [database name] character set utf8;
# 2. show databases;
# show create database [database name];
# 3. drop database [database name];
# 4. alter database [database name] character set gb2312;
# 5. use database [database name];
# 6. backup database:
# 1) bash cmd: mysqldump -uroot -p [database name]>[path]
# 2) in mysql:
# i. create the same sturcture database called testdb.
# ii. soucre [your backup db path]
*/
create database mydb1;
show databases;
-- 创建一个使用utf-8字符集的mydb2数据库。
create database mydb2 character set utf8;
-- 创建一个使用utf-8字符集并带校对规则的mydb3数据库。
create database mydb3 character set utf8 collate utf8_general_ci;
-- 演示备份(重要)
create database tt;
use tt;
create table a
(
name varchar(20)
);
insert into a(name) values('aaaa');
select * from a;
-- 看到a表有数据
-- 对tt作备份操作,启动一个window命令行窗口,执行如下命令
mysqldump -uroot -p tt>c:\tt.sql
-- 演示恢复
-- 1.先删除库
drop database tt;
-- 2.恢复tt库(1)
--2.1 为恢复库,要先创建库 create database tt;
--2.2 再恢复tt库
use tt;
source c:\tt.sql --(source:可以执行一个 sql脚本)
-- 3.恢复tt库(2)
--2.1 为恢复库,要先创建库 create database tt;
--2.2 恢复库 mysql -uroot -proot tt<c:\1.sql; (window命令)
/*
#--------------------------------------ops for tables------------------------------------------#
#syntax:
# 1. create table [table name]
# (
# [column name 1] [data type] [column constriants],
# [column name 2] [data type] [column constriants],
# [column name 3] [data type] [column constriants],
# ...
# [table constriants 1],
# [table constriants 1],
# ...
# );
# 2. drop table [table name];
# 3. alter table [table name] add column [column name] [data type] [constriants];
# alter table [table name] drop column [column name];
# 4. rename table [old table name] to [new table name];
*/
create table Shohin(
shohin_id char(4) not null,
shohin_mei varchar(100) not null,
shohin_bunrui varchar(32) not null,
hanbai_tanka integer ,
shiire_tanka integer ,
torokubi date ,
primary key (shohin_id)
);
drop table Shohin;
alter table Shohin add column shohin_mei_kana varchar(100);
alter table Shohin drop column shohin_mei_kana
rename table Sohin to Shohin;
/*
#----------------------------------------basics of SELECT---------------------------------------#
#1. syntax:
# select [columns]
# from [tables]
# where [conditions the rows,or called tuples, must sactify]
#2. select clause当中:
# 1). keyword-as:[column name] as [alias name],中文别名必须打双引号
# 2). keyword-distinct:
# 3). 可以存在"+, -, *, /, ()"等计算型运算符
#3. where clause 当中
# 1). 可以存在"+, -, *, /, ()"等计算型运算符,
# 2). 还可以存在“=, <>, >=, >, <=, <” 等比较运算符
# 3). 还可以存在“not, and, or”等逻辑运算符, SQL里面的逻辑运算为三值逻辑: true, false, unknown.
#4. NULL
# 1). 计算型运算中存在NULL,则结果一定为NULL;
# 2). 不能对NULL使用比较运算符,需要使用“is null” 或者 "is not null"
#5. unkonwn
# true or unkonwn = true
# false and unknown = false
*/
select *
from Shohin;
/*
mysql> select * from Shohin;
+-----------+------------+---------------+--------------+--------------+------------+
| shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka | torokubi |
+-----------+------------+---------------+--------------+--------------+------------+
| 0001 | T恤 | 衣服 | 1000 | 500 | 2009-09-20 |
| 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 |
| 0003 | 运动T恤 | 衣服 | 4000 | 2800 | NULL |
| 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 |
| 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 |
| 0006 | 叉子 | 厨房用具 | 500 | NULL | 2009-09-20 |
| 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 |
| 0008 | 圆珠笔 | 办公用品 | 100 | NULL | 2009-11-11 |
+-----------+------------+---------------+--------------+--------------+------------+
8 rows in set (0.00 sec)
*/
-- 为列设定别名
select shohin_id as id, shohin_mei as namae, shiire_tanka as tanka
from Shohin;
-- 设定汉语别名,记得打双引号
select shohin_id as "商品编号", shohin_mei as "商品名称" , shiire_tanka as "进货单价"
from Shohin;
-- 使用distinct删除shohin_bunrui列中重复的数据;
-- distinct 关键字只能写在 第一列 之前。
select distinct shohin_bunrui
from Shohin;
-- code2-8 null也算是一个数据
select distinct shiire_tanka
from Shohin;
-- code2-9 删除重复的 多列组合
select distinct shohin_bunrui, torokubi
from Shohin;
-- select clause 中 使用运算表达式 +. -, *,/, (),
select shohin_mei, hanbai_tanka, hanbai_tanka * 2 as hanbai_tanka_x2
from Shohin;
select shohin_mei, shohin_bunrui, hanbai_tanka*0.9 - shiire_tanka as rieki
from Shohin
where hanbai_tanka*0.9 - shiire_tanka >= 100
and (shohin_bunrui = '办公用品' or shohin_bunrui = '厨房用品');
/*
#------------------------------------aggregation and ordering---------------------------------#
#1. aggregation functions: count(), sum(), avg(), max(), min()
# 1) count():
# i. count(*)
# ii. count(distinct [column])
# 2) sum()
# 3) avg()
# i. 计算平均值前会事前排除 NULL值,也就排除了包含NULL的行的数目了。
# 4)max(),min()
# i. 这两个函数适用于几乎所有数据类型, 而sum(),avg()只适用于数值型。
#2. group by clause
# syntax:
# select [columns]
# from [tables]
# where [conditions]
# group by [column name 1],[columns name 2],...;
# 1)clause的执行顺序问题: from -> where -> group by -> having -> select
# 2) 含有group by的语句中:
# i. select子句中只能存在 常数,聚合函数,group by子句中指明的列名(也就是聚合键)
# ii. 在group子句中不能写列的别名。(可以这样思考,别名要在执行select的时候确定,但group by
# 子句执行在select子句之前,还没有别名,所以产生错误)
# iii. group by 子句显示的子句是无序的。
# iv. where 子句中不能出现聚合函数,理由分析同ii。
# v. 只有select子句和having子句才能有聚合函数
#3. having clause
# syntax:
# select [columns]
# from [tables]
# where [conditions]
# group by [column name 1],[columns name 2],...,
# having [分组结果对应的条件];
# 1)clause的执行顺序问题: from -> where -> group by -> having -> select
# 2)having 子句的构成要素:常数,聚合函数,group by子句中指明的列名(也就是聚合键)
# 3)对行的条件判断放在where子句里,对组的条件判断才放在having子句中。2)中的聚合键最好放在
# where子句中。
#4. order by clause
# syntax:
# select [columns]
# from [tables]
# where [conditions]
# group by [column name 1],[columns name 2],...,
# having [分组结果对应的条件];
# order by [column 1 desc/asc] [column 2 desc/asc]
# 1) order by子句写在select语句的末尾,默认排列顺序为升序。
# 2)排序键中可以显示用别名,从中可以推断语句的执行顺序如3)
# 3)子句的执行顺序: from -> where -> group by -> having -> select -> order by
# (after the execution of select clause, the result relation is given out.)
# 4) elect 子句中未包含的列也可以在order by子句中出现
# 5) 可以直接指出按照输出表的第几列来进行排序,但是不提倡。
*/
-- 计算包括NULL值的表的总行数。这个特性是count()特有,其他聚合函数不能将"*"作为参数。
select count(*)
from Shohin;
-- 计算null之外的shire_tankan的数据行数
select count(shiire_tanka)
from Shohin;
-- 计算取出重复数据后的数据行数(当然是)
select count(distinct shohin_bunrui)
from Shohin;
-- 和上面的结果是不一样的, 它它包括重复的值,不计入null.
select count(shohin_bunrui) from Shohin;
-- 只有一行,六列
select sum(hanbai_tanka), sum(shiire_tanka),
avg(hanbai_tanka), avg(shiire_tanka),
max(hanbai_tanka), min(shiire_tanka)
from Shohin;
-- 重要的语序问题: select -> from -> where -> group by -> having
-- clause的执行顺序问题: from -> where -> group by -> having -> select
select shohin_bunrui,count(*)
from Shohin
group by shohin_bunrui;
-- 聚合函数会分别在分好的各组中进行计算。 像上面就是 按照“shohin_bunrui”分成3组,然后
-- 分别对各组统计函数。
-- select shohin_mei, shohin_bunrui,count(*)
-- from Shohin
-- group by shohin_bunrui;
-- 其结果中 的 shohin_mei 不会正常显示。改正如下:
select shohin_mei, shohin_bunrui,count(*)
from Shohin
group by shohin_bunrui, shohin_mei;
-- 解释:这个分组有两层,第一层shohin_binrui,第二层在分好的shohin_binrui中在进行分类。
/*
mysql> select shohin_mei, shohin_bunrui,count(*)
-> from Shohin
-> group by shohin_bunrui, shohin_mei;
+------------+---------------+----------+
| shohin_mei | shohin_bunrui | count(*) |
+------------+---------------+----------+
| 圆珠笔 | 办公用品 | 1 |
| 打孔器 | 办公用品 | 1 |
| 叉子 | 厨房用具 | 1 |
| 擦菜板 | 厨房用具 | 1 |
| 菜刀 | 厨房用具 | 1 |
| 高压锅 | 厨房用具 | 1 |
| T恤 | 衣服 | 1 |
| 运动T恤 | 衣服 | 1 |
+------------+---------------+----------+
8 rows in set (0.00 sec)
mysql> select shohin_bunrui,count(*)
-> from Shohin
-> group by shohin_bunrui;
+---------------+----------+
| shohin_bunrui | count(*) |
+---------------+----------+
| 办公用品 | 2 |
| 厨房用具 | 4 |
| 衣服 | 2 |
+---------------+----------+
3 rows in set (0.00 sec)*/
-- 从通过商品种类进行聚合分组后的结果中,取出“包含的数据行数为2行”的组
select shohin_bunrui, count(*)
from Shohin
group by shohin_bunrui
having count(*) = 2;
select shohin_bunrui, avg(hanbai_tanka)
from Shohin
group by shohin_bunrui
having avg(hanbai_tanka) >= 2500;
/*
mysql> select shohin_bunrui, avg(hanbai_tanka)
-> from Shohin
-> group by shohin_bunrui
-> having avg(hanbai_tanka) >= 2500;
+---------------+-------------------+
| shohin_bunrui | avg(hanbai_tanka) |
+---------------+-------------------+
| 厨房用具 | 2795.0000 |
| 衣服 | 2500.0000 |
+---------------+-------------------+
2 rows in set (0.01 sec)
*/
select hanbai_tanka
from Shohin
group by hanbai_tanka
having hanbai_tanka > 500;
-- 上面这个语句中, having 里面的条件 更适合写在 where clause 里面。
-- 对行的条件判断放在where子句里,对组的条件判断才放在having子句中。
select hanbai_tanka
from Shohin
where hanbai_tanka > 500
group by hanbai_tanka;
select shohin_id, shohin_mei, hanbai_tanka, shiire_tanka
from Shohin
order by hanbai_tanka desc, shohin_id asc;
-- order by 子句可以使用列的别名
select shohin_id as id , shohin_mei, hanbai_tanka as ht, shiire_tanka
from Shohin
order by ht, id;
-- select 子句中未包含的列也可以在order by子句中出现
select shohin_mei, hanbai_tanka, shiire_tanka
from Shohin
order by shohin_id desc;
-- 可以直接指出按照输出表的第几列来进行排序(不提倡),下面指出按输出表
-- result_relation(id, shohin_mei, ht, shiire_tanka)第三列 ht 的降序排列的。
select shohin_id as id , shohin_mei, hanbai_tanka as ht, shiire_tanka
from Shohin
order by 3 desc;
/*
mysql> select shohin_id as id , shohin_mei, hanbai_tanka as ht, shiire_tanka
-> from Shohin
-> order by 3 desc;
+------+------------+------+--------------+
| id | shohin_mei | ht | shiire_tanka |
+------+------------+------+--------------+
| 0005 | 高压锅 | 6800 | 5000 |
| 0003 | 运动T恤 | 4000 | 2800 |
| 0004 | 菜刀 | 3000 | 2800 |
| 0001 | T恤 | 1000 | 500 |
| 0007 | 擦菜板 | 880 | 790 |
| 0002 | 打孔器 | 500 | 320 |
| 0006 | 叉子 | 500 | NULL |
| 0008 | 圆珠笔 | 100 | NULL |
+------+------------+------+--------------+
8 rows in set (0.00 sec)
*/
/*
#------------------------------------------INSERT, DELETE and UPDATE--------------------------------------#
#1. INSERT
# syntax:
# insert into [table name] ([column 1], [column 2],...) values ([value 1], [value 2],..);
# 1) 看下面示例掌握(fr. code4-1 to code4-12)
# 2)insert语句中的select语句中,可以使用where子句或者group by子句等热河sql语法(但使用order by子句并不
# 会产生任何影响。
#2. DELETE
# syntax:
# delete from [table name]
# where [conditions] --[optional]
# 1) 通过code4-13 to code 4-14 掌握, btw,delete * from ..是错误的。
# 2)Delete语句只能使用where子句,不能使用 group by,having,order by子句。
#3. UPDATE
# syntax:
# update [table name]
# set [column name] = [表达式]
# where [conditions] --[optional]
# 1) 通过 code4-15 to code4-20 掌握。
#4. TRANSACTION
# 1)注意概念理解
# 2)事务的ACID特性: atomicity, consistency,isolation, durability
*/
-- code4-1 sample table used to test
create table ShohinIns(
shohin_id char(4) not null,
shohin_mei varchar(100) not null,
shohin_bunrui varchar(32) not null,
hanbai_tanka integer default 0,
shiire_tanka integer ,
torokubi date ,
primary key (shohin_id)
);
-- code4-2 插入一行数据
insert into ShohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka,
shiire_tanka, torokubi) values ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
-- code4-A 插入多行, mysql ver.
INSERT INTO ShohinIns values ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'),
('0003', '运动T恤', '衣服', 4000, 2800, NULL),
('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
INSERT INTO ShohinIns VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
-- NULL
INSERT INTO ShohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi)
VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
-- code4-7 DEFAULT
INSERT INTO ShohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi)
VALUES ('0007', '擦菜板', '厨房用具', DEFAULT, 790, '2009-04-28');
-- 省略shiire_tanka列(无约束):默认插入NULL
INSERT INTO ShohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, torokubi)
VALUES ('0008', '圆珠笔', '办公用品', 100, '2009-11-11');
-- 省略shohin_mei列(NOT NULL约束):错误
INSERT INTO ShohinIns (shohin_id, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi)
VALUES ('0009', '办公用品', 1000, 500, '2009-12-12');
-- code4-9
-- 插入数据用的复制商品表
CREATE TABLE ShohinCopy
(shohin_id CHAR(4) NOT NULL,
shohin_mei VARCHAR(100) NOT NULL,
shohin_bunrui VARCHAR(32) NOT NULL,
hanbai_tanka INTEGER ,
shiire_tanka INTEGER ,
torokubi DATE ,
PRIMARY KEY (shohin_id));
-- code4-10 将商品表中的数据复制到复制商品表中
INSERT INTO ShohinCopy (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi)
SELECT shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi
FROM Shohin;
-- code4-11
-- 根据商品种类进行汇总用表
CREATE TABLE ShohinBunrui
(shohin_bunrui VARCHAR(32) NOT NULL,
sum_hanbai_tanka INTEGER ,
sum_shiire_tanka INTEGER ,
PRIMARY KEY (shohin_bunrui));
-- code4-12
INSERT INTO ShohinBunrui (shohin_bunrui, sum_hanbai_tanka, sum_shiire_tanka)
SELECT shohin_bunrui, SUM(hanbai_tanka), SUM(shiire_tanka)
FROM Shohin
GROUP BY shohin_bunrui;
-- code4-13 清空 Shohin表 ,但是保留Shohin
delete from Shohin;
-- 但要求是清空整个表的时候, mysql里面有效率更快的方式
truncate Shohin;
-- code4-14 删除部分数据行的搜索型delete.
delete from Shohin
where hanbai_tanka >= 4000;
-- code4-15 将登记日期全部更新为'2009-10-10'
update Shohin set torokubi = '2009-10-10';
-- code 4-16 将商品种类为厨房用具的记录的销售单价更新为原来的10倍
update Shohin
set hanbai_tanka = hanbai_tanka * 10
where shohin_bunrui = '厨房用具';
-- code 4-18
-- 1次UPDATE只更新1列
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka * 10
WHERE shohin_bunrui = '厨房用具';
UPDATE Shohin
SET shiire_tanka = shiire_tanka / 2
WHERE shohin_bunrui = '厨房用具';
-- code 4-19
-- 使用逗号对列进行分隔排列
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka * 10,
shiire_tanka = shiire_tanka / 2
WHERE shohin_bunrui = '厨房用具';
-- code 4-20
-- 将列用小括号括起来的列表形式
UPDATE Shohin
SET (hanbai_tanka, shiire_tanka) = (hanbai_tanka * 10, shiire_tanka / 2)
WHERE shohin_bunrui = '厨房用具';
-- code 4-21 事务提交
START TRANSACTION;
-- 运动T恤的销售单价下调1000日元
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
-- T恤的销售单价上浮1000日元
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤';
-- 觉得以上操作经检查,没错,提交commit.
COMMIT;
-- code 4-22 事务,返回进行事务前的状态
START TRANSACTION;
-- 运动T恤的销售单价下调1000日元
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = '运动T恤';
-- T恤的销售单价上浮1000日元
UPDATE Shohin
SET hanbai_tanka = hanbai_tanka + 1000
WHERE shohin_mei = 'T恤';
-- 觉得以上操作有问题,觉得要重新来,rollback.
ROLLBACK;