《MYSQL必知必会》摘要


前言

  • 记录一下《MYSQL必知必会》中学到的基础语法。

  • 按照看书的顺序,做一点摘要。

0、SQL语句的完整执行顺序

from : 将硬盘上的表文件加载到内存
where: 将符合条件的数据行摘取出来。生成一张新的临时表
group by :根据列中的数据种类,将当前临时表划分成若干个新的临时表
having : 可以过滤掉group by生成的不符合条件的临时表
计算所有表达式
select : 对当前临时表迚行整列读取
order by : 对select生成的临时表,迚行重新排序,生成新的临时表
limit : 对最终生成的临时表的数据行,迚行截取。

详见此处

SELECT birth,count(*) AS num,
       GROUP_CONCAT(work_time) AS work_times,
       GROUP_CONCAT(salary) AS salarys
FROM employee
WHERE work_time <= 320 #行筛选,work_time不超过320
GROUP BY birth
HAVING MAX(salary) >= 7200 #对组进行筛选,组内salary最大值要不小于7200

拿这个查询举例:

  • 先从 e m p l o y employ employ 表中检索出虚表,由于只有一个,所以不需要做笛卡尔积
  • 通过 w h e r e where where 字段筛去不符合的行
  • group by, 通过 b i r t h birth birth 子段分组
  • Having 语句, 对分好的组筛选
  • select中的表达式计算,得到新的表
  • 从新表中 select 出想要的字段

一、检索+排序+过滤

1.检索数据

1、检索若干列
SELECT COL1,COL2,COL3 
FROM TABLE1;
2、检索所有列
SELECT *
FROM TABLE1;
3.检索值不同的行
SELECT DISTINCT COL1
FROM TABLE1;

DISTINCT关键字,顾名思义,此关键字指示MySQL,只返回不同的值。
不能部分使用DISTINCT ,DISTINCT关键字作用于所有列而不仅是前置它的列。

4、限制结果
SELECT COL1
FROM TABLE1 
LIMIT 1,5

返回列COL1 从第1行开始的5行。 (mysql中默认从第0行开始)

2.排列检索数据

为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。
SELECT COL1
FROM TABLE1 
ORDER BY COL1,COL2;

只有在COL1中的值相同的行中,才会利用COL2的值进行排序。
默认是升序,如果要降序需要指定关键字DESC :

SELECT COL1
FROM TABLE1 
ORDER BY COL1 DESC,COL2 DESC;
利用ORDER BY 和 LIMIT 找出列COL1的最大值:
SELECT COL1
FROM TABLE1 
ORDER BY COL1 DESC
LIMIT 1

在给出ORDER BY子句时,应该保证它
位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY
之后。使用子句的次序不对可能产生错误消息。
ORDER BY子句必须是SELECT语句中的最后一条子句。

3.过滤数据

where 子句操作符:

在这里插入图片描述

空值NULL的检查:
SELECT * FROM employee
WHERE BIRTH IS NULL;
#返回BIRTH的值为NULL的所有行

4.数据过滤

逻辑操作符AND 、OR : AND的优先级高于OR,但混搭的时候一定要加括号啊。
IN操作符: IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。
          IN取合法值的由逗号分隔的清单,全都括在圆括号中。
NOT操作符: WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。
#IN操作符的例子
SELECT * FROM employee
WHERE BIRTH IN (1990,1997,1985) ;
#返回BIRTH 等于1990 OR 1997 OR 1985 的所有行

5.利用通配符进行过滤

前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共同点是过滤中使用的值都是已知的。但是如果遇到像要匹配包含文本"114514"的所有产品这类问题,使用简单的操作符肯定不行的。需要用到通配符(wildcard,用来匹配值的一部分的特殊字符)。

在搜索子句中使用通配符,必须使用LIKE操作符。
LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。

①通配符"%":在搜索串中,%表示任何字符出现任意次数。

SELECT * FROM employee
WHERE BIRTH LIKE '199%';
#返回满足BIRTH是199开头的字符串的行 ,不要求birth一定是string类型。
SELECT * FROM employee
WHERE HOMETOWN LIKE '%芜湖%';
#返回满足HOMETOWN包含"芜湖"的行,如:芜湖,安徽芜湖 ,芜湖厨师 ,安徽芜湖厨师
SELECT * FROM employee
WHERE NAME LIKE 'F%K';
#返回满足F开头,K结尾的NAME行 。如F**K

%无法匹配NULL。

PS:在MYSQL中,搜索是区分大小写的。

②通配符"_":在搜索串中,_匹配单个字符。 有且只是1个。

SELECT * FROM employee
WHERE NAME LIKE 'SHI_T';
#返回诸如SHIFT SHITT 的行

6.用正则表达式进行搜索

正则表达式是用来匹配文本的特殊的字符串。如果你想从一个文本文件中提取电话号码,可以使用正则表达式。 (比如在"123456789"中匹配"123456"。)

1.关键字的REGEXP用法:

SELECT * FROM employee
WHERE ID REGEXP '123a';
#返回ID包含'123a'的行
#LIKE '123a' 返回等于'123a'的行,REGEXP则是包含
#另外REGEXP也是不区分大小写的,如果要区分需要使用BINARY关键字:WHERE ID REGEXP BINARY '123a'

2.为搜索两个串之一(或者为这个串,或者为另一个串),可使用’|',如下所示:

SELECT * FROM employee
WHERE ID REGEXP '123a | 123b | 123c | 123d';
#'|'从功能上类似于在SELECT语句中使用OR语句,多个OR条件可并用

3.上面是匹配一个字符串,但是如果我们只想匹配特定的单个字符,怎么办?
可通过指定一组字符用’[’ 和 ']'括起来,得到一个字符集合来完成。

SELECT * FROM employee
WHERE ID REGEXP '[123]';
#[123]是[1|2|3]的缩写 , [123]也可以缩写成[1-3]
#同样的 [abcde] 可以缩写成[a-e]

3.正则表达式’.'可以匹配任意一个字符,不可以是0个。

正则表达式语言由具有特定含义的特殊字符构成。我们已经看到 “.” 、“[]”、
“|“和”-“等。如果要匹配这些,需要加转义前缀” \\”。

SELECT * FROM employee
WHERE address REGEXP '\\.';
#匹配address中包含"."的行

4.匹配多个实例:
上面的实例都是不限定出现次数的匹配。如果我们需要限定出现次数,需要用到重复元字符。
在这里插入图片描述

SELECT * FROM employee
WHERE student REGEXP '\\([0-9] friends?\\)';
#匹配student中包含的"([0-9] friends?)"行, "s"可以出现也可以不出现

5.定位符 :以上的匹配都是不限定位置的匹配,如果说限定在开头出现 、在结尾出现等待,就需要用到定位符。
在这里插入图片描述

6.在这里插入图片描述
7.
在这里插入图片描述
返回:在这里插入图片描述

二、创建计算字段+数据处理函数+数据汇总+子查询

1.创建计算字段

字段(field) 基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。

SELECT Concat(name , '(' ,id,')')
FROM employee
#返回的列就是一个计算字段

返回:
在这里插入图片描述
PS:多数DBMS使用+来实现拼接(如ACCESS),MySQL则使用Concat()函数来实现。

2.使用别名。

上面的例子得到的计算字段名字就是Concat(name , '(' ,id,')'),不好看。
我们可以使用别名让它好看起来。
别名(alias)是一个字段或值的替换名。用AS关键字赋予。
SELECT Concat(name , '(' ,id,')') AS member
FROM employee
#返回列的名字就是member

在这里插入图片描述

3.执行算术计算

计算字段的另一常见用途是对检索出的数据进行算术计算。
SELECT salary/work_time AS average_salary,
       Concat(name, '(' ,id,')') AS member
FROM employee 
#返回第一列是salary/work_time的值

在这里插入图片描述

2.使用数据处理函数

1.文本处理函数
在这里插入图片描述
在这里插入图片描述
2.日期和时间处理函数
在这里插入图片描述
3.数值处理函数
在这里插入图片描述

3.数据汇总

1.聚集函数

当我们需要:

  • 确定表中行数(或者满足某个条件或包含某个特定值的行数)。
  • 获得表中行组的和。
  • 找出表列(或所有行或某些特定的行)的最大值、最小值和平均
    值。

这些信息不必要把某几列全部检索出来,而是需要一个汇总信息。
为方便这种类型的检索,MySQL给出了5个聚集函数,见下表。
这些函数能进行上述罗列的检索。
在这里插入图片描述

#例子:
SELECT MAX(salary/work_time) AS average_salary_max,
       MIN(salary/work_time) AS average_salary_min,
       SUM(salary/work_time) AS average_salary_sum
FROM employee
#返回平均薪水最大值 最小值  和

返回:
在这里插入图片描述

可以用DISTINCT关键字限定聚合函数只作用于不同的值,放在指定列名前

4.分组数据

本节将介绍如何分组数据,以便能汇总表内容的子集。
这涉及两个新SELECT语句子句,分别是GROUP BY子句和HAVING子句。

1.利用GROUP BY 子句创建分组。

SELECT birth,count(*)
FROM employee
GROUP BY birth

返回:
在这里插入图片描述

  • GROUP BY子句让数据库按birth排序并分组,这导致count(*)是对每个分组进行计算而并非是整个表。

2.查看每组的具体数据。

我们分完组后,每个列只会显示组内的一条信息,如果要看到全部信息,需要用到 GROUP_CONCAT()函数。

SELECT birth,count(*),
       GROUP_CONCAT(name),
       GROUP_CONCAT(DEPARTMENT)
FROM employee
GROUP BY birth
#按birth分组,每组的name ,department都会全部显示

返回:
在这里插入图片描述

3.GROUP BY子句的一些使用规则:
在这里插入图片描述

4.分组后的数据总和

使用ROLLUP 使用WITH ROLLUP关键字,
可以得到每个分组以及每个分组汇总级别(针对每个分组)的值

拿上面的举例子:

SELECT birth,count(*),
       GROUP_CONCAT(name),
       GROUP_CONCAT(DEPARTMENT)
FROM employee
GROUP BY birth WITHROLLUP
#使用WITH ROLLUP 相当于在返回表的底下增加一栏汇总

返回:
在这里插入图片描述

  • 如果是按两列进行分组,WITH ROLLUP会对每个二级分组汇总,然后对一级分组汇总。
SELECT birth,sex,count(*),
       GROUP_CONCAT(name),
       GROUP_CONCAT(DEPARTMENT)
FROM employee
GROUP BY birth,sex WITH ROLLUP

返回:
在这里插入图片描述

5.过滤分组

如果我们想要列出至少有两个订单的所有顾客。为得出这种数据,必须基于完整的分组而不是个别的行进行过滤。
·
我们已经看到了WHERE子句的作用。但是,在这个例 子中WHERE不能完成任务,因为WHERE过滤指定的是行而不是分组。WHERE没有分组的概念。
·
那么,不使用WHERE使用什么呢?MySQL为此目的提供了另外的子句,那就是HAVING子句。HAVING非常类似于WHERE。
·
事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。

SELECT birth,count(*) AS num,
       GROUP_CONCAT(name) AS names,
       GROUP_CONCAT(DEPARTMENT) AS DEPARTMENTs
FROM employee
GROUP BY birth WITH ROLLUP
HAVING count(*) BETWEEN 1 AND 3
#把行数不在[1,3]范围的组筛出去 
#因为汇总组的行数只有1,所以这里会把汇总组也筛出去

返回:
在这里插入图片描述

例子:
当我们需要返回work_time不超过320,按birth分组后,组内存在salary超过7200的数据。

SELECT birth,count(*) AS num,
       GROUP_CONCAT(work_time) AS work_times,
       GROUP_CONCAT(salary) AS salarys
FROM employee
WHERE work_time <= 320 #行筛选,work_time不超过320
GROUP BY birth
HAVING MAX(salary) >= 7200 #对组进行筛选,组内salary最大值要不小于7200

返回:
在这里插入图片描述

5.子查询(subquery)

即嵌套在其他查询中的查询。

(从这节开始,我们使用关系表)

1.利用子查询进行过滤

例1.

问题描述:订单存储在两个表中。对于包含订单号、客户ID、订单日期的每个订单,
orders表存储一行。
各订单的物品存储在相关的orderitems表中。
orders表不存储客户信息。它只存储客户的ID。
实际的客户信息存储在customers表中。
现在,假如需要列出订购物品TNT2的所有客户,应该怎样检索?

步骤:
在这里插入图片描述

SELECT cust_name
FROM customers
WHERE  cust_id IN 
(
    SELECT cust_id
    FROM orders 
    WHERE order_num IN 
    ( 
        SELECT order_num
        FROM orderitems
        WHERE  pro_id = 'TNT2'
    )
)                   

例2.

问题描述:读者信息,图书信息,借阅信息,图书种类信息分别存储在四个关系表中,求所借图书都未归还的读者的读者编号。

步骤:
①:利用子查询从借阅表中返回有归还标记的读者编号, 即:返回列中的所有读者编号满足至少归还了一本图书
②:从读者中选出借过书且不在①返回表中的读者编号
SELECT DISTINCT(读者.读者编号),读者.姓名
FROM 读者,借阅
WHERE 读者.读者编号 = 借阅.读者编号
AND 读者.读者编号 NOT IN 
(
    SELECT                   
    借阅.读者编号
    FROM 借阅
    WHERE 是否归还=1
)

返回:
在这里插入图片描述
2.作为计算字段使用子查询

例1.

从读者表中检索读者编号和姓名,同时统计每个读者借了几本书,输出借的书的编号 ,归还了几本书,输出归还的书的编号。

#从读者表中检索读者编号和姓名,同时统计每个读者借了几本书,还了几本书
#同时输出借的书的编号,已归还的书的编号
SELECT  读者.读者编号,读者.姓名,
( 
    SELECT count(*) 
    FROM 借阅
    WHERE 借阅.读者编号 = 读者.读者编号
) AS 借阅数目,
( 
    #使用GROUP_CONCAT()函数将返回的多行拼接成一行
    SELECT GROUP_CONCAT(借阅.图书编号)
    FROM 借阅
    WHERE 借阅.读者编号 = 读者.读者编号
) AS 所借书籍 ,
( 
    SELECT count(*) 
    FROM 借阅
    WHERE 借阅.读者编号 = 读者.读者编号
    AND 借阅.是否归还 = 1
) AS 归还数目 ,
( 
    #使用GROUP_CONCAT()函数将返回的多行拼接成一行
    SELECT GROUP_CONCAT(借阅.图书编号)
    FROM 借阅
    WHERE 借阅.读者编号 = 读者.读者编号
    AND 借阅.是否归还 = 1
) AS 归还图书 
FROM 读者

返回:
在这里插入图片描述

三、联结表

本章将介绍什么是联结,为什么要使用联结,如何编写使用联结的
SELECT语句。

1.关系表

1.为什么要使用关系表

在数据库的设计中,相同数据出现多次决不是一件好事,此因素是关系数据库设计的基础。关系表的设计就是要保证把信息分解成多个表,一类数据一个表。各表通过某些常用的值(即关系设计中的关系(relational))互相关联。

分解数据为多个表能更有效地存储,更方便地处理,并且具有更大的可伸缩性。但这些好处是有代价的。如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?
答案是使用联结。简单地说,联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。

2.创建联结

SELECT DISTINCT(读者.读者编号),读者.姓名
FROM 读者,借阅
WHERE 读者.读者编号 = 借阅.读者编号
上面的例子就是通过WHERE子句联结读者和借阅表,选出在借阅表中出现过的读者编号

利用WHERE子句建立联结关系似乎有点奇怪,但实际上,有一个很充分的理由。在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。

在联结两个表时,你实际上做的是将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,它只筛选出那些匹配给定条件(这里是联结条件)的行。
简单点说,我们把两个表联结起来,就相当于两个表各自保留在对方中出现过的行,然后并成一个大表。 如果保留结束后两个表的行数不一样,即:某个表有重复值的情况下,处理方法可以看到下面的例子

我们开始有两个表:t1,t2

表t1
t1
表t2
t2

#按属性a联结起来
SELECT *
FROM t1,t2
WHERE t1.a = t2.a
ORDER BY t1.a

返回:
在这里插入图片描述

t1中会保留三行,t2中会保留两行。所以返回结果会保留三行,t2缺少的行会复制补全。

3.内部联结

上面的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内部联结。 可以有另一种等价的写法。

SELECT DISTINCT(读者.读者编号),读者.姓名,读者.性别
FROM 读者 INNER JOIN 借阅
ON 读者.读者编号 = 借阅.读者编号;
#两种写法是等价的
SELECT DISTINCT(读者.读者编号),读者.姓名
FROM 读者,借阅
WHERE 读者.读者编号 = 借阅.读者编号;

返回:
在这里插入图片描述

4.联结多个表

SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系。

例1.
返回除图书编号为001-000011之外的,被借过的图书的图书编号,借的读者的读者编号,姓名,性别

这里需要联结三个表,分别通过主键和外键相联
  • 写法①:直接用WHERE联结
SELECT  读者.读者编号
       ,读者.姓名 
       ,读者.性别 
       ,图书.图书编号
FROM 读者,图书,借阅
WHERE 读者.读者编号 = 借阅.读者编号 
AND 图书.图书编号 = 借阅.图书编号 
AND 图书.图书编号 <> '001-000011' 
ORDER BY 读者.读者编号,图书.图书编号 
  • 写法②:用INNER JOIN ON进行内联结
SELECT  读者.读者编号
       ,读者.姓名 
       ,读者.性别 
       ,图书.图书编号
FROM 
(读者
	INNER JOIN 借阅
	ON 读者.读者编号 = 借阅.读者编号 
)
INNER JOIN 图书 ON 图书.图书编号 = 借阅.图书编号 

WHERE 图书.图书编号 <> '001-000011'

ORDER BY 读者.读者编号,图书.图书编号 
  • 写法③:子查询
SELECT  读者.读者编号,读者.姓名,读者.性别,借阅.图书编号
FROM 读者,借阅
WHERE 读者.读者编号 IN 
(
    SELECT 借阅.读者编号 WHERE 借阅.图书编号 <> '001-000011'
)
AND 借阅.图书编号 <> '001-000011'
ORDER BY 读者.读者编号,借阅.图书编号 
	从SQL语句执行顺序来看,这三个方法的底层逻辑是一样的:先通过筛选条件得到一个相应列满足要求的联结表,然后从中SELECT出需要的东西返回。

返回:
在这里插入图片描述

INNER JOIN ON联结多个表的写法为:

 FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) 
 INNER JOIN 表3
 ON 表1.字段号=表3.字段号

例2.
返回满足所借的书的单价和大于等于120的所有读者的借书总数,读者编号,姓名,所借图书的名称,总价。

分析:题目要返回每个读者的借书集合,借书总价,这就需要用到GROUP BY子句来分组了。 我们可以写一个简单的联结查询来完成这题。

SELECT COUNT(*)
    ,读者.姓名
    ,借阅.读者编号
    ,GROUP_CONCAT(图书.图书名称)
    ,SUM(单价) AS 总价
FROM 读者,借阅,图书
WHERE 读者.读者编号 = 借阅.读者编号
AND 借阅.图书编号 = 图书.图书编号
GROUP BY  读者.姓名,读者.读者编号
HAVING SUM(单价) >= 120
ORDER BY COUNT(*),读者.读者编号;
#运行顺序:将读者 借阅 图书 三个表连起来,按读者.姓名,读者.读者编号分组
#,使用聚合函数过滤出总价不小于120的组,再SELECT出我们要的信息


#或者用INNER JOIN ON 的写法
SELECT COUNT(*)
    ,读者.姓名
    ,借阅.读者编号
    ,GROUP_CONCAT(图书.图书名称)
    ,SUM(单价) AS 总价
FROM (读者 INNER JOIN 借阅 ON 读者.读者编号 = 借阅.读者编号 )
INNER JOIN 图书 ON 借阅.图书编号 = 图书.图书编号
GROUP BY 读者.姓名,读者.读者编号
HAVING SUM(单价) >= 120
ORDER BY COUNT(*),读者.读者编号

#考虑过用子查询去写,但是写8出

返回:

在这里插入图片描述

四、创建高级联结

1.使用表别名

别名除了用于列名和计算字段外,SQL还允许给表名起别名。
这样做有两个主要理由:
①缩短SQL语句
②允许在单条SELECT语句中多次使用相同的表(自联结)

2.自联结

把若干个相同的表联结起来

例子:返回分类号是001的所有图书的图书名称

SELECT T1.图书名称
FROM 图书 AS T1, 图书 AS T2
WHERE T1.图书名称 = T2.图书名称
AND T2.分类号 = '001'
#WHERE把2个图书列表并了起来(本质求作笛卡尔积),并筛除了不满足等号条件的行
#T1是第一个表的别名 T2是第二个表的别名 ,其实和普通的联结理解起来是一样的
#如果不适用别名,直接写成 图书.图书名称 = 图书.图书名称
#系统不晓得图书指的是第一个列表还是第二个

这个例子当然也可用子查询来完成。

返回:
在这里插入图片描述

在这里插入图片描述

3.自然联结

自然联结其实和内部联结一样,只是不会出现相同的重复列。
内部联结返回所有数据,甚至相同的列多次出现。自然联结每个列只返回一次。(存在数据列没有被显示出来)

4.外部联结

外部联结中包含了在相关表中没有关联的行。
外联语句:LEFT OUTER JOIN ON/ RIGHT OUTER JOIN ON(左联/右联)

什么是没有关联的行呢? 我们先举一个内部联结的例子:
假设我们有表t1,t2

t1:
在这里插入图片描述

t2:
在这里插入图片描述
可以看到t1和t2有相同列a 。
于是内部联结:

SELECT *
FROM t1,t2
WHERE T1.A = T2.A

返回:
在这里插入图片描述

如果是外部联结:

SELECT *
FROM t1 LEFT OUTER JOIN t2
ON T1.A = T2.A
#T1左联T2

则返回:
在这里插入图片描述

  • 可以看到返回表中出现了带null的行,这些行就是在两个表中没有关联的行,在这里的具体含义是属性a的值不相等的行。

  • 表t1中没有联结的行也被插入了返回表中。

  • 之所以是t1是因为我们这里用了LEFT关键字,选择了左表为基准,基准表没有联结的行也会被插入返回表,该行的另一个表的值就设成null。

5.使用联结的注意事项

在这里插入图片描述

五.组合查询

多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compound query)。

有两种基本情况需要使用组合查询:
在这里插入图片描述

1.使用UNION创建组合查询

UNION的使用很简单。所需做的只是给出每条SELECT语句,在各条语句之间放上关键字UNION

问题描述:假设我们需要从图书表中返回分类号为001的图书,以及返回单价不超过50的图书的图书名称。

如果我们不使用组合查询:

SELECT 图书名称
FROM 图书
WHERE 图书.分类号 = '001' OR 单价 <= 50

返回:
在这里插入图片描述

如果使用组合查询:

SELECT 图书名称
FROM 图书
WHERE 图书.分类号 = '001' 
UNION 
SELECT 图书名称
FROM 图书
WHERE 图书.单价 <=50 

返回结果一样。

在这个简单的例子中,使用UNION可能比使用WHERE子句更为复杂。
但对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据的情形,使用UNION可能会使处理更简单。

2.UNION使用规则

  • UNION必须在至少2条SELECT语句组成的查询中出现,并且每两个相邻的SELECT语句之间必须要有UNION衔接。
  • UNION并起来的SELECT语句必须具有相同的列、表达式、聚合函数,不过顺序可以不一样。
  • 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型。

3.UNION ALL

刚刚的例子中,使用UNION返回的表去除了相同的行,这与WHERE是一样的处理方法。如果我们需要把所并的表完完整整的不去重地表现出来,可以使用UNION ALL
在这里插入图片描述

4.对组合查询结果排序

在用UNION组合查询时,只能使用一条ORDER BY子句,并且它必须出现在最后一条SELECT语句之后。

六.插入数据

1.INSERT语句

在这里插入图片描述
1.插入完整的行

  • 要求指定表名 ,每一行的数值都要按格式给出,或者用NULL代替
INSERT INTO T3
VALUES ('E3','W3','Q3'); #通过values子句给出行值
SELECT * #插入数据后的查看
FROM T3;
这种按一行的插入语法很简单,但是并不安全,因为数据的插入顺序严格依赖于列值的次序。

应该尽量避免这种写法。而采取下面这种:

INSERT INTO T3(E,W,Q) #指定了插入列的次序
VALUES ('E3','W3','Q3'); #通过values子句给出行值
SELECT * #查看插入后的数据
FROM T3;

这种指定了插入列次序的写法,可以只将需要插入的列给出,新行的其余列会默认为NULL

2.插入多行

插入多行的做法就是在VALUES子句中用,把每组数据分隔开即可。

INSERT INTO T3(E,W,Q) 
VALUES ('E3','W3','Q3'),
       ('E4','W4','Q4');
SELECT * #查看插入后的数据
FROM T3;

3.插入检索出的数据 (INSERT SELECT语句)

我们把表T2中的数据插入到表T3:

INSERT INTO T3(E,W,Q) 
SELECT E,F,A 
FROM T2;
SELECT * 
FROM T3;

INSERT SELECT不关心返回列的列名,只按位置插入。

七.更新和删除数据

1.更新数据

1.UPDATA语句
在这里插入图片描述

UPDATA语句基本上只有三部分组成:

  • 要更新的表
  • 列名和它们的新值
  • 确定要更新行的过滤条件

举例:把id为’1005’的客户的类别信息更新成 ‘0005’

UPDATA 客户 #指定表名
SET 类别信息 = '0005' #设定更新列以及更新的值,可以设定为NULL表示删除某一列
WHERE id = '1005' #筛选出需要更新的行  筛选过程也就是
#UPDATA语句以WHERE子句作为结束

更新多列的值:

UPDATA 客户 #指定表名
SET 类别信息 = '0005', #每个更新用 , 分隔就行
	身份信息 = '15'
WHERE id = '1005' #筛选出需要更新的行  筛选过程也就是
#UPDATA语句以WHERE子句作为结束,如果没有WHERE将更新 

在这里插入图片描述

在这里插入图片描述

2.删除数据

在这里插入图片描述

在这里插入图片描述

八.创建和操纵表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值