mysql常用语句

列:字段 
行:一条记录 
表中一行记录对应一个Java对象的数据 
SQL:Structure Query Language。(结构化查询语言)

SQL被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准,后来被国际化标准组织(ISO)采纳为关系数据库语言的国际标准。

各数据库厂商都支持ISO的SQL标准。普通话

各数据库厂商在标准的基础上做了自己的扩展。方言

DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等; CREATE、 ALTER、DROP

DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据); INSERT、 UPDATE、 DELETE

DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别;

DQL(Data Query Language):数据查询语言,用来查询记录(数据)。

注意:sql语句以;结尾

操作数据库

create {database|schema} [if not exists] db_name
    [create_specification[,create_specification]...]

create_specification:
    [default] character set charset_name //指定字符集
   |[default] collate collation_name  //指定数据库字符集的比较方式(校验规则)

字符集,character set,就是一套表示字符的符号和这些的符号的底层编码;而校验规则,则是在字符集内用于比较字符的一套规则。下面我简单举个例子来说明一下:如在某个字符集“X”的A与a,他们的底层编码分别是A=0,a=100。这里符号“A”“a”和底层编码“0”“100”就是字符集的概念范围。假设我们要比较A与a的大小,我们得到a>A,因为我们是根据其底层编码进行比较的,这就是这个字符集“X”的一种校验规则“Z”(根据底层编码来比较)。假设,现在有另外一种校验规则,是先取其相反数,然后再比较大小,那么就很显然的得到a < A,这就是字符集“X”的另外一种校验规则“Z1”。由此可见,一种字符集可能存在多个与之对应的校验规则。

创建数据库
create databse mydb1;

创建数据库并设置编码格式为gbk。不指定的话默认为utf-8,这个在安装的时候设置了
create database mydb2 character set gbk;

设置校验规则
create database mydb3 character set gbk collate gbk_chinese_ci;

查看当前数据库服务器中的所有数据库
show databases;

查看前面创建的mydb2数据库的定义信息
show create database mydb2;

删除前面创建的mydb3数据库
drop database mydb3;

把mydb2的字符集修改为utf8
alter database mydb2 set utf8;

查看当前使用的数据库
select database();

切换数据库
use mydb2;

注释

敲完两个短线之后要敲一个空格

select * from student;-- 注释
  • 1

操作数据库表

常用数据类型

  • int :整型,4个字节
  • double:浮点型,例如double(5,2)表示最多5位,其中2位为小数,即最大值为999.99。
  • varchar:可变长度字符串类型。varchar(10) ‘aaa’ 占3位
  • datetime:日期时间类型。yyyy-MM-dd hh:mm:ss
  • char:固定长度字符串类型。char(10) ‘aaa ’ 占10位
  • text:大文本字符串类型
  • blob:字节类型
  • date:日期类型,格式为:yyyy-MM-dd
  • time:时间类型,格式为:hh:mm:ss
  • timestamp:时间戳类型 yyyy-MM-dd hh:mm:ss 会自动赋值

字符串类型和日期类型都要用单引号括起来。

空值:null

创建表

create table 表名(
    字段名 类型(长度) [约束],
    字段名 类型(长度) [约束]
);

字符类型:varchar(n)

这里写图片描述

单表约束

主键约束:primary key,要求被修饰的字段:唯一和非空
唯一约束:unique,要求被修饰的字段:唯一
非空约束:not null,要求被修饰的字段:非空

查看表

查看数据库中的所有表:show tables;
查看表结构:desc 表名;
查看表的创建细节:show create table 表名;

删除表

drop table 表名;
  •  

修改表

alter table 表名 add 列名 类型(长度) [约束]; --添加列
alter table 表名 modify 列名 类型(长度) [约束]; --修改列的类型长度及约束
alter table 表名 change 旧列名 新列名 类型(长度) [约束]; --修改表列名
alter table 表名 drop 列名; --删除列
alter table 表名 character set 字符集; --修改表的字符集
rename table 表名 to 新表名; --修改表名

对表的增删改

插入记录:insert

insert into 表(列名1,列名2,列名3..) values(值1,值2,值3..);--向表中插入某些列
insert into 表 values(值1,值2,值3..); --向表中插入所有列

列名与列值的类型,个数,顺序要一一对应。可以把列名当做Java中的形参,把列值当做实参。

值不要超出列定义的长度。值如果是字符串或者日期需要加单引号。

在cmd中敲代码插入中文数据会报错,解决方案查看 
ERROR 1366 (HY000): Incorrect string value-解决方案 - 杨钊 - CSDN博客 
http://blog.csdn.net/zsx157326/article/details/77012242

更新记录:update

update 表名 set 字段名=值,字段名=值...; --这个会修改所有的数据,把一列的值都变了
update 表名 set 字段名=值,字段名=值... where 条件;

删除记录:delete

delete from 表名  --删除表中所有记录
delete from 表名 where 条件
truncate table 表名;

delete删除表中的数据,是一条一条删除,不清空auto_increment记录数;删除后的数据如果在一个事务中还可以找回。

truncate删除是把表直接drop掉,重新建表,auto_increment将置为零。删除的数据不能找回。执行速度比delete快。

数据查询语言DQL

简单查询

查询所有列
select * from stu;
查询指定列
select sid,sname,age from stu;

别名查询

as可以省略
表别名
select * from product as p;
列别名
select pname as pn from product;

去掉重复值

用来去除重复数据,是对整个结果集(结果集就是查出来的那些数据)进行数据重复抑制的,而不是针对某一列。
select distinct Department,SubCompany from Employee;

计算字段

字段间计算
select age*salary,name from employee;

运算查询
select pname,price+10 from product;

comm列有很多记录的值为NULL,因为任何东西与NULL相加结果还是NULL,所以结算结果可能会出现NULL。下面使用了把NULL转换成数值0的函数IFNULL
 select *,sal+ifnull(comm,0) from emp;

条件查询

where后的条件写法

  • = != <> < <= > >=
  • between…and
  • in(set)
  • and
  • or
  • not
  • is null
  • like,_代表任意一个字符,%代表任意0-n个字符
select * from stu where gender='female' and age<50;
select * from stu where sid='S_1001' and sname='lisi';
select * from stu where sid in('S_1001','S_1002','S_1003');
select * from stu where sid not in('S_1001','S_1002','S_1003');
select * from stu where age is null;
select * from stu where age>=20 and age<=40;
select * from stu where age between 20 and 40;
select * from stu where stu where gender!='male';
select * from stu where gender<>'male';
select * from stu where not gender='male';
select * from stu where not sname is null;
select * from stu where sname is not null;
select * from stu where sname like '_____'; -- 查询姓名由5个字母构成的学生记录
select * from stu where sname like '____i'; -- 查询姓名由5个字母构成,并且第5个字母为“i”的学生
select * from stu where sname like 'z%'; -- 查询姓名以“z”开头的学生记录
select * from stu where sname like '_i%';-- 查询姓名中第2个字母为“i”的学生记录
select * from stu where sname like '%a%';-- 查询姓名中包括“a”字母的学生记录

排序

select * from stu order by age asc; -- 升序排序,也可以不加asc,默认为升序
select * from stu order by age desc; --降序
select * from emp order by sal desc,empno asc;-- 按月薪降序排序,如果月薪相同时,按编号升序排序。只有在前一个条件相同时,后一个条件才会起作用。

聚合函数

聚合函数是用来做纵向运算的函数

  • count():统计指定列不为null的记录行数
  • max():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算
  • min():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算
  • sum():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0。求和的时候忽略null,如果都是null,则算出来的结果为null。
  • avg():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0.
select count(*) as cnt from emp;-- 计算emp表中记录数
select count(comm) cnt from emp;-- 查询emp表中拥有佣金的人数,因为count()函数中给出的是comm列,那么只统计comm列非null的行数。
select count(*) from emp where sal>2500;-- 查询emp表中月薪大于2500的人数
select count(comm),count(mgr) from emp; -- 查询有佣金的人数,以及由领导的人数
select sum(sal) from emp; -- 查询所有雇员的佣金和
select sum(sal),sum(comm) from emp; -- 查询所有雇员月薪和,以及所有雇员佣金和
select sum(sal+ifnumm(comm,0)) from emp; -- 查询所有雇员月薪+佣金和
select avg(sal) from emp;
select max(sal),min(sal) from emp;-- 查询最高工资和最低工资

分组查询

当需要分组查询时需要使用group by子句,例如查询每个部分的工资和,就需要使用部门来分组。

注:凡是和聚合函数同时出现的列名,则一定要写在group by之后

select deptno,sum(sal) from emp group by deptno;-- 查询每个部门的编号和每个部门的工资和
select deptno,count(*) from emp group by deptno;-- 查询每个部门的部门编号以及每个部门的人数
select deptno,count(*) from emp where sal>1500 group by deptno;-- 查询每个部门的编号以及每个部门工资大于1500的人数

这里写图片描述

执行了select deptno,sum(sal) from emp group by deptno;之后

这里写图片描述

执行了select deptno,count(*) from emp where sal>1500 group by deptno;之后

这里写图片描述

这句话是先把sal>1500的都查出来,然后再从查出来的这里边查

having子句

where是在分组前对数据进行过滤,having是在分组后对数据进行过滤。

having后面可以使用聚合函数,where不可以使用聚合函数。

select deptno,sum(sal) from emp group by deptno having sum(sal)>9000;
  •  

这里写图片描述

limit(方言,MySQL特有的)

limit用来限制查询结果的起始行,以及总行数

select * from emp limit 0,5; -- 查询5行记录,起始行从0开始。起始行从0开始,即从第一行开始
select * from emp limit 3,10;-- 查询10行记录,起始行从3开始。就是从第4行开始查

分页查询

如果一页记录为10条,希望查看第3页应该怎么查呢?

  • 第一页记录起始行为0,一共查询10行
  • 第二页记录起始行为10,一共查询10行
  • 第三页记录起始行为20,一共查询10行

查询语句的执行顺序

查询语句书写顺序:select-from-where-group by-having-order by-limit

查询语句执行顺序:from-where-group by-having-select-order by-limit

from决定从哪儿获取数据,where,group by,having决定决定显示那几行,select决定显示的列,order by对列进行排序,limit觉得获取哪些数据。

这里写图片描述

一步一步的筛选数据。

数据的完整性

数据的完整性只对增删改有作用,对查询数据没有限制。

作用:保证用户输入的数据保存到数据库中是正确的

确保数据的完整性=在创建表时给表中添加约束

完整性的分类:

  • 实体完整性
  • 域完整性
  • 引用完整性

实体完整性

实体:即表中的一行(一条记录)代表一个实体

实体完整性的作用:标识每一行数据不重复

约束类型:主键约束(primary key) 唯一约束(unique) 自动增长列(auto_increment)

主键约束

每个表都要有一个主键。数据唯一,且不能为null。

第一种添加方式
create table student(
    id int primary key,
    name varchar(50)
);

第二种添加方式:此种方式优势在于,可以创建联合主键。但一般都不用联合主键
create table student(
    id int,
    name varchar(50),
    primary key(id)
);

create table student(
    classid int,
    stuid int,
    name varchar(50),
    primary key(classid,stuid)
);

第三种添加方式
create table student(
    id int,
    name varchar(50)
);
alter table student add primary key(id);

唯一约束

特点:数据不能重复

create table student(
    id int,
    name varchar(50) unique
);

自动增长列

给主键添加自动增长的数值,列只能是整数类型

create table student(
    id int primary key auto_increment,
    name varchar(50)
);
insert into student(name) values('tom');

域完整性

域完整性的作用,限制此单元格的数据正确,不对照此列的其他单元格比较

域代表当前单元格

域完整性约束:

  • 数据类型
  • 非空约束(not null)
  • 默认值约束(default)
create table student(
    id int primary key,
    name varchar(50) not null
);

create table student(
    id int primary key,
    name varchar(50) not null,
    sex varchar(10) default '男'
);

引用完整性(参照完整性)

外键约束:foreign key

create table student(
    id int primary key,
    name varchar(50) not null
);

create table score(
    id int primary key,
    score int,
    sid int,-- 外键,student表的id,数据类型要和student表中的一样
    courseid,--外键
    constraint fk_student_score_sid foreign key(sid) references student(id)
);
-- 另一种添加方式
alter table score add constraint fk_student_score_sid foreign key(sid) references student(id);

student表是主表,score是从表。从表中的数据参照主表里的数据。

  • 先建立主表,后建立从表
  • 从表中的数据是从主表中获得的, 从表不能够添加主表中不存在的数据。
  • 主表不能够删除从表中已经使用的数据。如果要删除表的话,要先删除从表,再删除主表。

如果没有外键约束的话,score表中sid的值可以随意写。但这样不符合逻辑。现在添加约束,让这两张表有联系,添加完之后,score表中的sid的值只能是student表中的id值,不能写其他的。

  • 从表外键的值是对主表主键的引用。
  • 从表外键类型,必须与主表主键类型一致。

表与表之间的关系

  • 一对多关系

    • 常见实例,部门和员工。
    • 建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键。
  • 多对多关系

    • 常见实例:学生和课程
    • 多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这个两个字段分别作为外键指向各自一方的主键。(就是将一个多对多拆分成两个一对多)
    • 两张表分别都是主表,第三张表为从表,提供两个字段,都是外键。

这里写图片描述

  • 一对一关系(了解)

    • 例如人和身份证。这种情况需要找出主从关系,即谁是主表,谁是从表。人可以没有身份证,但身份证必须要有人才行,所以人是主表,而身份证是从表。
    • 在实际开发中应用不多,因为一对一可以创建成一张表
    • 两种建表原则
    • 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique。(就是给从表的添加上唯一约束和外键约束)
    • 外键是主键:主表的主键和从表的主键,形成主外键关系。(就是给从表添加上主键约束和外键约束)
-- 主表
create table QQ(
    qqid int primary key,
    password varchar(50)
);
-- 从表
create table QQDetail(
    qqid int primary key,-- 设置主键
    name varchar(50),
    address varchar(200)
);
-- 给从表设置外键
alter table QQDetail add constraint fk_QQ_QQDetail_qqid foreign key(qqid) references QQ(qqid);

多表查询

合并结果集

create table A(
    name varchar(10),
    score int
);

create table B(
    name varchar(10),
    score int
);

insert into A values('a',10),('b',20),('c',30);-- 这种语法可以插入三条数据
insert into B values('a',10),('b',20),('d',40);

先建立两个表,各插入一条数据。

这里写图片描述

union,合并两个或多个select语句的结果集。条件:每个结果集必须有相同的列数,相容的数据类型。

union运算符合并了两个查询结果结果集,其中完全重复的数据被合并为了一条。如果要返回所有记录,在后边添加all。

select * from A
union
select * from B;

select * from A
union all
select * from B;

连接查询

一对一的例子

-- 创建数据库
create database shop;

-- 使用数据库
use shop;


-- 分类表
create table category(
    cid varchar(32) primary key,
    cname varchar(100)
);

-- 商品表
create table product(
    pid varchar(32) primary key,
    name varchar(40),
    price double
);

-- 添加外键字段 category_id
alter table product add column category_id varchar(32);

-- 添加约束
alter table product add constraint product_fk foreign key (category_id) references category (cid);


-- 分类表
insert into category(cid,cname) values('c001','家电');
insert into category(cid,cname) values('c002','服饰');
insert into category(cid,cname) values('c003','化妆品');

-- 商品
insert into product(pid,name,price,category_id) values('p001','联想',5000,'c001');
insert into product(pid,name,price,category_id) values('p002','海尔',3000,'c001');
insert into product(pid,name,price,category_id) values('p003','雷神',5000,'c001');

insert into product(pid,name,price,category_id) values('p004','JACK JONES',800,'c002');
insert into product(pid,name,price,category_id) values('p005','真维斯',200,'c002');
insert into product(pid,name,price,category_id) values('p006','花花公子',440,'c002');
insert into product(pid,name,price,category_id) values('p007','劲霸',2000,'c002');

insert into product(pid,name,price,category_id) values('p008','香奈儿',800,'c003');
insert into product(pid,name,price,category_id) values('p009','相宜本草',200,'c003');

多对多的例子

-- 订单表
create table orders(
    oid varchar(32) primary key,
    totalprice double
);

-- 订单项表
create table orderitem(
    oid varchar(50),-- 订单id
    pid varchar(50) -- 商品id
);

-- 联合主键(可省略)
alter table orderitem add primary key(oid,pid);

-- 订单表和订单项表的主外键关系
alter table orderitem add constraint orderitem_orders_fk foreign key(oid) references orders(oid);

-- 商品表和订单项表的主外键关系
alter table orderitem add constraint orderitem_product_fk foreign key(pid) references product(pid);

现在主要看分类表和商品表,一个分类对应很多商品

这里写图片描述

1.交叉连接查询(基本不会使用-得到的是两个表的乘积)

  • 语法:select * from A,B;
select * from category,product;

这里写图片描述

category有3行数据,product有9行数据,最终结果有27行数据。

类似这样的我用红线勾出的数据,cid和category_id对应不上,这样的数据没啥用。

连接查询会产生笛卡尔积,假设A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。

产生这样的结果并不是我们想要的,可以通过条件过滤去除重复。通常要查询的多个表之间都存在关联关系,那么就通过关联关系去除笛卡尔积。

2.内连接查询(使用关键字inner join – inner可省略)

select * from category,product where cid=category_id;

  • 隐式内连接:select * from A,B where 条件;
  • 显示内连接:select * from A inner join B on 条件;(这种方式是标准写法)
-- 1.查询那些分类的商品已经上架
-- 隐式内连接
select * from category,product where cid=category_id;
select * from category c,product where c.cid=product.category_id;
select cname from category c,product p where c.cid=p.category_id;
select distinct cname from category c,product p where c.cid=p.category_id;

-- 内连接
select * from category inner join product on cid=category_id;
select * from category join product on cid=category_id where price>3000;
select * from category join product on cid=category_id;

select 
    c.cid,c.cname,p.name 
from 
    category c 
join product p on c.cid=p.category_id;

这里写图片描述

这是这句话select * from category join product on cid=category_id;查出来的数据,之后可以添加各种条件再对这个结果集进行筛选。

3.外连接查询(使用关键字outer join –outer可以省略)

select * from category left join product on cid=category_id;

  • 左外连接:left outer join 
    • select * from A left outer join B on 条件
  • 右外连接:right outer join 
    • select * from A right outer join B on 条件

左连接是先查询出左表(即以左表为主),然后查询右表,右表中满足条件的显示出来,不满足条件的显示null.

比如我现在在category表中添加一条数据

insert into category values('c004','生活用品');

然后执行

select * from category left join product on cid=category_id;

这里写图片描述

而用内连接的话

select * from category join product on cid=category_id;

显示结果还是

这里写图片描述

如果这时候我想查询每类商品的数量,这时候只能用左连接查询。

select 
    cname,count(category_id) 
from 
    category 
left join product on cid=category_id group by cname;

查询结果为

这里写图片描述

如果用内连接的话,会少一行数据

select 
    cname,count(category_id) 
from 
    category 
join product on cid=category_id group by cname;

这里写图片描述

连接查询不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。多表连接,至少要有n-1个条件。

两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,当不是很熟悉连接查询时,首先要学会去除笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。

先添加三条数据

-- 向订单表中添加数据
insert into orders(oid,totalprice) values('o001',3800);

-- 向订单和产品的中间表添加数据
insert into orderitem(oid,pid) values('o001','p002');
insert into orderitem(oid,pid) values('o001','p002');
select 
    orders.oid,orders.totalprice,product.name,product.price
from 
    orders 
join orderitem on orders.oid=orderitem.oid
join product on orderitem.pid=product.pid;

-- 也可以写成
select 
    orders.oid,orders.totalprice,product.name,product.price
from 
    orders,orderitem,product
where orders.oid=orderitem.oid and orderitem.pid=product.pid;

这里写图片描述

自然连接

大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式: 
两张连接的表中名称和类型完全一致的列作为条件,例如emp和dept表都存在deptno列,并且类型一致,所以会被自然连接找到!

select * from emp natural join dept;-- 内连接
select * from emp natural left join dept;-- 左连接
select * from emp natural right join dept;-- 右连接

子查询

SQL语句允许将一个查询语句做为一个结果集供其他SQL语句使用,就像使用普通的表一样,被当作结果集的查询语句被称为子查询。

若结果集为单行单列(标量子查询),则可放在select或where语句中

若结果集为多行单列,可放在where语句中,配合in使用

若结果集中有多行多列(就相当于一个表,派生表),一般作为数据源进行再一次检索。

-- 查询与SCOTT同一个部门的员工
select * from emp where deptno=(select deptno from emp where ename='SCOTT');
-- 查询工作和工资与MARTIN完全相同的员工信息
select * from emp where (job,sal) in (select job,sal from emp where ename='MARTIN');
-- 查询有2个以上直接下属的员工信息
select * from emp where empno in (select mgr from emp group by mgr having count(mgr)>=2);
-- 查询员工编号为7788的员工名称、员工工资、部门名称、部门地址
select e.ename,e.sal,d.dname,d.loc from emp e,(select dname,loc,deptno from dept) d where e.deptno=d.dep

转载于:https://my.oschina.net/u/3286465/blog/1997178

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值