mysql语句详细总结(未完成,持续更新)

mysql语句总结

登录服务器

mysql -p host -u user -p

回车后输入密码:

Enter password: 

ok,登录成功,可以进行基本操作了

基本的不能在基本的操作

输入一个简单的查询命令(查询服务器版本号和当前日期)

select version(), current_date ;

创建数据库

create database test;

使用数据库

use test;

假如说:我记得我上次创建了一个数据库呢,你还让我创建,我不想创建,但是我忘了上次创建的数据库名字。

#当然可以,查看存在的数据库名字
show databases;

#使用你想使用的数据库
use empolyes;

嗯,可以愉快的使用之前的数据库了
假如说:我想看一下这个数据库里边有哪些表

#照猫画虎
show tables;

嗯?不对,走的实用路线,为什么会有这种花里胡哨的没用的东西,”假如“可能不知道有SqlLyog这个软件

假如:我想查看表的字段

#查看表customers的字段
show columns from customers;

它对每个字段返回一行,行中包含字段名、数据
类型、是否允许 NULL 、键信息、默认值以及其他信息

显示广泛的服务器状态信息

 show status;

显示创
建特定数据库或表的MySQL语句

show create database 数据库名;

show create table 表名;

显示授予用户(所有用户或特定用户)的安
全权限

show grants;

创建表


create table t_test (
	id  int auto_increment primary key  
	name varchar(32),  
	url varchar(32) 
);

修改创建表的基操

  • 表的约束
  1. 主键约束 primary key

    a. 请移步上边创建表的那个地方

    b. 第二种方法,id作为主键

create table t_test(     
	id int auto_increment,
	name varchar(32),
	url varchar(32),
	PRIMARY KEY(id) 
); 

    c. 第三种方法,表已经创建好了,需要添加(修改)主键

ALTER TABLE t_test DROP PRIMARY KEY ,ADD PRIMARY KEY (id) ;
  1. 非空 (Not Null)
    a. 创建表的时候直接给name添加非空约束
create table t_test (
	id  int auto_increment primary key,  
	name varchar(32) not null,
	url varchar(32)  
);

    b. 修改字段(url)字段为非空约束(相当于直接更改url字段,第一个url是原表中的字段,第二个url是修改后的名称,相同就是不改名字)

ALTER TABLE t_test CHANGE COLUMN url url varchar(32) NOT NULL;

    c. 删除字段(url)非空约束

alter table t_test  modify url varchar(32) null;
  1. 唯一约束(unique)
    a. 创建url唯一约束
create table t_test (
	id  int auto_increment primary key,  
	name varchar(32) not null,
	url varchar(32) unique 
);

    b. 修改字段(name)为唯一约束

ALTER TABLE t_test  ADD UNIQUE (name);

   c. 删除字段(name)的唯一性约束

ALTER TABLE t_test  DROP INDEX name;
  1. 外键约束(foreign key)
    首先创建一个表t_test
create table t_test (
	id  int(22) auto_increment primary key,  
	name varchar(32) not null,
	url varchar(32) unique 
);

    a.直接创建外键约束(注意:两个表连接字段需要类型及长度需要相同)

create table t_formary(
 id int auto_increment primary key,
 hlsxn varchar(32),
 t_tid int(22),
 FOREIGN KEY (t_tid ) REFERENCES t_test(id)
);

    b. 增加外键

create table t_formary(
 id int auto_increment primary key,
 hlsxn varchar(32),
 t_tid int(22)
);
#添加外键约束(CONSTRAINT formary_t_tid可选,为外键约束命名)
CONSTRAINT formary_t_tid alter table t_formary add foreign key(t_tid) references t_test(id);

   c.删除外键

# 一般不用(外键名称可在添加外键时指定,否则为默认的)
alter table demo drop foreign key 外键名称;

指定默认值(delfaut)

create table orderitems(
  order_num int not null,
  order_item int not null,
  prod_id char(10) not null,
  item_price decimal(8,2) not null default 1,
  primary key (order_num,order_item);
)engine=InnoDB;

更新表

添加一列

#给 vendors 表增加一个名为 vend_phone 的列,必须明确其数据类型
alter table vendors 
  add vend_phone char(20);

删除刚刚添加的列,可以这样做

alter table vendors drop column vend_phone;

重命名表

使用 RENAME TABLE 语句可以重命名一个表

rename table customers To customers2;

视图

视图的应用

 重用SQL语句。
 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。
 使用表的组成部分而不是整个表。
 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。
 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。

创建

create view as select 语句

查看视图

 show create view 视图名 

删除视图

drop view 视图名

更新视图限制

 分组(使用 GROUP BYHAVING );
 联结;
 子查询;
 并;
 聚集函数( Min()Count()Sum() 等);
 DISTINCT;
 导出(计算)列。
 DISTINCT;
 导出(计算)列。

存储过程

 通过把处理封装在容易使用的单元中,简化复杂的操作(正如前面例子所述)。
 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。
 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化

总结一下:简单、安全、高性能
but, 缺点

 一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验
 你可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程

创建存储过程

#此存储过程名为productpricing ,用 CREATE PROCEDURE productpricing() 语句定义。如果存储过程接受参数,它们将在 () 中列举出来。此存储过程没有参数,但后跟的 () 仍然需要。 BEGIN 和 END 语句用来限定存储过程体,过程体本身仅是一个简单的 SELECT 语句
create procedure productpricing()
Begin
  select avg(prod_price) as priceaverage
  from products
End;

注意!!!!!

mysql 命令行客户机的分隔符 如果你使用的是 mysql 命令行实用程序,应该仔细阅读此说明。默认的MySQL语句分隔符为 ; (正如你已经在迄今为止所使用的MySQL语句中所看到的那样)。 mysql 命令行实用程序也使用 ; 作为语句分隔符。如果命令行实用程序要解释存储过程自身内的 ; 字符,则它们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误。
解决办法是临时更改命令行实用程序的语句分隔符,如下所示:
delimiter //
create procedure productpricing()
Begin 
  select * from products ;
end //
delimiter ;

其中, DELIMITER // 告诉命令行实用程序使用 // 作为新的语
句结束分隔符,可以看到标志存储过程结束的 END 定义为 END
// 而不是 END; 。这样,存储过程体内的 ; 仍然保持不动,并且
正确地传递给数据库引擎。最后,为恢复为原来的语句分隔符

删除存储过程

drop procedure productpricing;
# drop procedure productpring if exists;

使用参数

create procedure productpricing(
  out p1 decimal(8,2),
  out ph decimal(8,2)
)
begin 
  select Min(prod_price)
  into p1
  from products;
  select Max(prod+price)
  into ph
  from products;
end;

调用

call productpricing(@pricelow, @pricehigh);
#所有MySQL变量都必须以 @ 开始。
select @pricelow, @pricehigh;

检查存储过程

show create procedure ordertotal;
#为了获得包括何时、由谁创建等详细信息的存储过程列表,使用 SHOW  PROCEDURE STATUS
#SHOW PROCEDURE STATUS 列出所有存储过程。为限制其输出,可使用 LIKE 指定一个过滤模式
show procedure status Like 'ordertotal';

游标(cursor)

 在能够使用游标前,必须声明(定义)它。这个过程实际上没有
检索数据,它只是定义要使用的 SELECT 语句。
 一旦声明后,必须打开游标以供使用。这个过程用前面定义的SELECT 语句把数据实际检索出来。
 对于填有数据的游标,根据需要取出(检索)各行。
 在结束游标使用时,必须关闭游标。

创建游标

create procedure processorders()
begin 
  declare ordernumbers cursor
  for 
  select order_num from orders;

打开和关闭游标

open ordernumbers;
#CLOSE 释放游标使用的所有内部内存和资源,因此在每个游标不再需要时都应该关闭
close ordernumbers;
#隐含关闭 如果你不明确关闭游标,MySQL将会在到达 END 语句时自动关闭它。
create procedure processorders()
begin 
  -- Declare local variables
  Declary o int;
  -- Declare the cursor
  Declare ordernumbers cursor
  for select order_num 
  from orders;
  -- open the cursor
  open ordernumbers;
  -- get order number
  fetch rodernumbers into o;
  -- close the cursor
  close ordernumbers;
end;
create procedure processorders()
begin
  -- Declare local variables
  Declare done boolean default 0;
  declare o int;
  declare t decimal(8,2);

  -- Declare the cursor 
  declare ordernumbers cursor
  for select order_num from orders;
  -- Declare continue handler
  declare continue handler for sqlstate '02000' set done=1;

 -- create a table to store the results
 create table if not exists ordertotals(
  order_num int,
  total decimal(8,2)
);

  -- open the cursor
  open ordernumbers;
  
  -- loop through all rows
  repeat
    -- get order number
    fetch ordernumbers into o;

  -- get the total for this order
  call ordertotal(o, 1, t);

  insert order and totoal
  insert into ordertotals 
  values(o,t);
  -- end of loop
  until done end repeat;

  -- close the cursor
  close ordernumbers;
end;
#增加了另一个名为 t 的变量(存储每个订单的合计)。此存储过程还在运行中创建了一个新表(如果它不存在的话),名为 ordertotals 。这个表将保存存储过程生成的结果。 
#FETCH像以前一样取每个 order_num ,然后用 CALL 执行另一个存储过程(我们在前一章中创建)来计算每个订单的带税的合计(结果存储到 t )。最后,
#用 INSERT 保存每个订单的订单号和合计。

触发器(trigge)

 唯一的触发器名;
 触发器关联的表;
 触发器应该响应的活动( DELETEINSERTUPDATE );
 触发器何时执行(处理之前或之后)。
create trigger newproduct afier
  insert on products for
  each row select 'Product added"';
#CREATE TRIGGER 用来创建名为 newproduct 的新触发器。触发器可在一个操作发生之前或之后执行,这里给出了 AFTER INSERT ,
#所以此触发器将在 INSERT 语句成功执行后执行。这个触发器还指定 FOREACH ROW ,因此代码对每个插入行执行。
#在这个例子中,文本 Productadded 将对每个插入的行显示一次。

删除触发器

drop trigger 名字;

insert触发器

 在 INSERT 触发器代码内,可引用一个名为 NEW 的虚拟表,访问被插入的行;
 在 BEFORE INSERT 触发器中, NEW 中的值也可以被更新(允许更改被插入的值);
 对于 AUTO_INCREMENT 列, NEW 在 INSERT 执行之前包含 0 ,在 INSERT执行之后包含新的自动生成值。
create trigger neworder  
after insert 
on orders 
for each row select new.order_num;
#注意:MySQL5以后不支持返回结果集,需要在最后加上 into 

#此代码创建一个名为 neworder 的触发器,它按照 AFTER INSERTON orders 执行。
#在插入一个新订单到 orders 表时,MySQL生成一个新订单号并保存到 order_num 中。触发器从 NEW. order_num 取得这个值并返回它。
#此触发器必须按照 AFTER INSERT 执行,因为在 BEFOREINSERT 语句执行之前,新 order_num 还没有生成。
#对于 orders 的每次插入使用这个触发器将总是返回新的订单号(MySQL5后没有返回值)

delete触发器

 在 DELETE 触发器代码内,你可以引用一个名为 OLD 的虚拟表,访问被删除的行;
 OLD 中的值全都是只读的,不能更新
create trigger deleteorder 
before delete
on orders for each row
begin
  insert into archive_orders(order_num,order_date,cust_id)
  values(old.order_num,old.order_date,old.cust_id);
end;
#在任意订单被删除前将执行此触发器。它使用一条 INSERT 语句将 OLD 中的值(要被删除的订单)
#保存到一个名为 archive_orders 的存档表中(为实际使用这个例子,你需要用与 orders 相同的列创建一个名为 archive_orders 的表)。

使用 BEFORE DELETE 触发器的优点(相对于 AFTER DELETE 触器来说)为,如果由于某种原因,订单不能存档, DELETE 本身将被放弃

UPDATE触发器

 在 UPDATE 触发器代码中,你可以引用一个名为 OLD 的虚拟表访问以前( UPDATE 语句前)的值,引用一个名为 NEW 的虚拟表访问新更新的值;
 在 BEFORE UPDATE 触发器中, NEW 中的值可能也被更新(允许更改将要用于 UPDATE 语句中的值);
 OLD 中的值全都是只读的,不能更新。
#保证州名缩写总是大写(不管 UPDATE 语句中给出的是大写还是小写)
create trigger updatevendor
before update on vendors
for each row set new.vend_state = upper(new.vend_state);

引擎类型

InnoDB 是一个可靠的事务处理引擎(参见第26章),它不支持全文
本搜索;
 MEMORY 在功能等同于 MyISAM ,但由于数据存储在内存(不是磁盘)
中,速度很快(特别适合于临时表);
 MyISAM 是一个性能极高的引擎,它支持全文本搜索(参见第18章),
但不支持事务处理。

更多知识请点击这里

基本查询操作

查询customers表所有字段

select * from customers;

查询某个字段

select cust_name from customers;

查询多个字段

select cust_name,cust_address from customers;

去重复(distinct)

select distinct(去重字段名) from customers;

#不要括号也可以
select distinct 去重字段名 from customers;

分页(只查询某连续行)limit 下标从0开始

#查询从结果第1行开始的三行  下标从0开始
select cust_id from customers limit 0,3;
#查询第5行开始的10行下标从0开始
select * from customers limit 6,10 
#查询第4行开始的15行,如果从4行开始只有3行数据,不够那么多就只显示三行 下标从0开始
select * from customers limit 5,15;

对查询结果排序(order by)

#默认升序,
select * from products order by 排序字段;
#如果需要按照多个字段排序,则在order by后边跟着需要排序的字段,逗号分隔
#降序在降序字段后添加desc即可
select * from products order by prod_price desc, prod_name;

实战:有一个products表,有字段prod_price为商品价格,请找到最昂贵的一个商品。

select * from products
    order by prod_price desc
    limit 1;
#小知识点:limit 1相当于limit 0,1;

模糊查询(like %通配符)

#查询名称以jet开头的记录
select * from products where prod_name like 'jet%';
#查询名称包含anvil的记录
select * from products where prod_name like '%anvil%';
# s 起头以 e 结尾的所有产品
select * from products where prod_name like 's%e';

模糊查询(like )下划线( _ )通配符

区别在于_只能匹配单个字符,而%匹配任意字符

正则匹配查询(regexp)

#与上述作用相同
select * from products where prod_name regexp 'anvil';

需要注意,默认不区分大小写,需要添加binary关键字

select * from products where prod_name regexp binary 'JetPack .000';

匹配字符类

[:alnum:] 任意字母和数字(同[a-zA-Z0-9][:alpha:] 任意字符(同[a-zA-Z][:blank:] 空格和制表(同[\\t][:cntrl:] ASCII控制字符(ASCII 031127[:digit:] 任意数字(同[0-9][:graph:][:print:]相同,但不包括空格
[:lower:] 任意小写字母(同[a-z][:print:] 任意可打印字符
[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:] 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v][:upper:] 任意大写字母(同[A-Z][:xdigit:] 任意十六进制数字(同[a-fA-F0-9]

匹配重复字符

* 0个或多个匹配
+ 1个或多个匹配(等于{1,})
? 0个或1个匹配(等于{0,1})
{n} 指定数目的匹配
{n,} 不少于指定数目的匹配
{n,m} 匹配数目的范围(m不超过255

查询结果拼接字符串(Concat())

#多数DBMS使用 + 或 || 来实现拼接,
#MySQL则使用 Concat() 函数来实现。当把SQL语句转换成
#MySQL语句时一定要把这个区别铭记在心
select Concat(cend_name,'(',vend_country,')')
     from vendors
     order by vend_name

结果为这样的格式:name(location)
去掉数据右侧空格: RTrim()

Trim 函数 MySQL除了支持 RTrim() (正如刚才所见,它去掉
串右边的空格),还支持 LTrim() (去掉串左边的空格)以及
Trim() (去掉串左右两边的空格)。

别名:

别名还有其他用途。常见的用途包括在实际
的表列名包含不符合规定的字符(如空格)时重新命名它,在
原来的名字含混或容易误解时扩充它,等等。

常用函数

Left() 返回串左边的字符
Length() 返回串的长度
Locate() 找出串的一个子串
Lower() 将串转换为小写
LTrim() 去掉串左边的空格
Right() 返回串右边的字符
RTrim() 去掉串右边的空格
Soundex() 返回串的SOUNDEX值
SubString() 返回子串的字符
Upper() 将串转换为大写

常用日期函数

AddDate() 增加一个日期(天、周等)
AddTime() 增加一个时间(时、分等)
CurDate() 返回当前日期
CurTime() 返回当前时间
Date() 返回日期时间的日期部分
DateDiff() 计算两个日期之差
Date_Add() 高度灵活的日期运算函数
Date_Format() 返回一个格式化的日期或时间串
Day() 返回一个日期的天数部分
DayOfWeek() 对于一个日期,返回对应的星期几
Hour() 返回一个时间的小时部分
Minute() 返回一个时间的分钟部分
Month() 返回一个日期的月份部分
Now() 返回当前日期和时间
Second() 返回一个时间的秒部分
Time() 返回一个日期时间的时间部分
Year() 返回一个日期的年份部分

数值处理函数

Abs() 返回一个数的绝对值
Cos() 返回一个角度的余弦
Exp() 返回一个数的指数值
Mod() 返回除操作的余数
Pi() 返回圆周率
Rand() 返回一个随机数
Sin() 返回一个角度的正弦
Sqrt() 返回一个数的平方根
Tan() 返回一个角度的正切

聚合函数

AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

分组函数(group by)

select * from products
    where prod_price >= 10
    group by vend_id
#可以使用having进行过滤
select * from products
    where prod_price >= 10
    group by vend_id
    having count(vend_id) >= 2;

内连接(inner join)

select * from vendors inner join products
    on vendors.vend_id = products.vend_id;

还可以自连接 假如你发现某物品(其ID为 DTNTR )存在问题,因此想知道生产该物
品的供应商生产的其他物品是否也存在这些问题。此查询要求首先找到
生产ID为 DTNTR 的物品的供应商,然后找出这个供应商生产的其他物品

select p1.prod_id,p1.prod_name from products p1,products p2 where p1.vend_id = p2.vend_id and p2.prod_id = 'dtntr';

外连接( OUTER JOIN)在使用 OUTER JOIN 语法时,必须使用RIGHT 或 LEFT 关键字指定包括其所有行的表( RIGHT 指出的是 OUTER JOIN 右边的表,而 LEFT指出的是 OUTER JOIN 左边的表) 一般省略outer
并且 left join 也可以和right join 互换

select c.cust_id,o.order_num
    from customers c left join orders o
    on o.cust_id = c.cust_id;

组合查询(union)
举一个例子,假如需要价格小于等于 5 的所有物品的一个列表,而且还想包括供应商 1001 和 1002 生产的所有物品(不考虑价格)。当然,可以利用 WHERE 子句来完成此工作,不过这次我们将使用 UNION
首先我们来看单条sql语句:

select vend_id, prod_id, prod_price
    from products
    where prod_price <= 5;

在这里插入图片描述

select vend_id, prod_id, prod_price
   from products
   where vend_id in (1001,1002);

在这里插入图片描述
只需要将两个select使用union连接起来即可

select vend_id, prod_id, prod_price
    from products
    where prod_price <= 5
union
 select vend_id, prod_id, prod_price
   from products
   where vend_id in (1001,1002);

在这里插入图片描述
union规则

UNION 必须由两条或两条以上的 SELECT 语句组成,语句之间用关键字 UNION 分隔(因此,如果组合4SELECT 语句,将要使用3UNION 关键字)。
 UNION 中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。
 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)
UNION 必须由两条或两条以上的 SELECT 语句组成,语句之间用关键字 UNION 分隔(因此,如果组合4SELECT 语句,将要使用3UNION 关键字)。
 UNION 中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。
 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)

**注意union默认去重的,可以观察上边结果,如果不需要去重使用UNION ALL即可 **
全文本搜索

MySQL
支持几种基本的数据库引擎。并非所有的引擎都支持本书所描述的全文本搜索。两个最常使用的引擎为 MyISAM 和 InnoDB ,前者支持全文本搜索,而后者不支持。

select note_text
    from productnotes
    where match(note_text) against('rabbit');

布尔操作符

+ 包含,词必须存在
- 排除,词必须不出现
> 包含,而且增加等级值
< 包含,且减少等级值
() 把词组成子表达式(允许这些子表达式作为一个组被包含、
排除、排列等)
~ 取消一个词的排序值
* 词尾的通配符
"" 定义一个短语(与单个词的列表不一样,它匹配整个短语以
便包含或排除这个短语)
#这个搜索匹配包含词 rabbit 和 bait 的行。
select note_text
    from productnotes
    where match(note_text) against('+rabbit +bait' in boolean mode);
    

插入(insert)

如果数据检索是最重要的(通常是这样),则你可以通过在INSERTINTO 之间添加关键字 LOW_PRIORITY ,指示MySQL降低 INSERT 语句的优先级,如下所示:
insert low_priority into
insert into test(列名) values();

更新(update)

update customers set 字段名='值' where 条件
IGNORE 关键字 如果用 UPDATE 语句更新多行,并且在更新这些行中的一行或多行时出一个现错误,则整个 UPDATE 操作被取消(错误发生前更新的所有行被恢复到它们原来的值)。为即使是发生错误,也继续进行更新,可使用 IGNORE 关键字
update ignore customers

删除(delete)

delete customers where 条件
更快的删除 如果想从表中删除所有行,不要使用 DELETE 。可使用 TRUNCATE TABLE 语句,它完成相同的工作,但速度更快( TRUNCATE 实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)
发布了7 篇原创文章 · 获赞 0 · 访问量 107

猜你喜欢

转载自blog.csdn.net/weixin_44188300/article/details/103706003