欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySQL常用语句

程序员文章站 2024-01-24 16:02:22
...

列:字段
行:一条记录
表中一行记录对应一个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;-- 注释

操作数据库表

常用数据类型

  • 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)

MySQL常用语句

单表约束

主键约束: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 intovalues(值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的人数

MySQL常用语句

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

MySQL常用语句

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

MySQL常用语句

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

having子句

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

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

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

MySQL常用语句

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觉得获取哪些数据。

MySQL常用语句

一步一步的筛选数据。

数据的完整性

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

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

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

完整性的分类:

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

实体完整性

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

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

约束类型:主键约束(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值,不能写其他的。

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

表与表之间的关系

  • 一对多关系

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

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

MySQL常用语句

  • 一对一关系(了解)

    • 例如人和身份证。这种情况需要找出主从关系,即谁是主表,谁是从表。人可以没有身份证,但身份证必须要有人才行,所以人是主表,而身份证是从表。
    • 在实际开发中应用不多,因为一对一可以创建成一张表
    • 两种建表原则
    • 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一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);

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

MySQL常用语句

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);

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

MySQL常用语句

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

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

MySQL常用语句

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;

MySQL常用语句

这是这句话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;

MySQL常用语句

而用内连接的话

select * from category join product on cid=category_id;

显示结果还是

MySQL常用语句

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

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

查询结果为

MySQL常用语句

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

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

MySQL常用语句

连接查询不限与两张表,连接查询也可以是三张、四张,甚至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;

MySQL常用语句

自然连接

大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它。而自然连接无需你去给出主外键等式,它会自动找到这一等式:
两张连接的表中名称和类型完全一致的列作为条件,例如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.deptno and e.empno=7788;
相关标签: mysql