MySQL必知必会读书笔记(上)【1-17章】

unbuntu系统安装MySQL

1、更新本地索引,执行

sudo apt update

在这里插入图片描述
2、利用在线安装

sudo apt install mysql-server

在这里插入图片描述
3、输入命令验证安装版本

 mysql --version

在这里插入图片描述
4、安装后,MySQL服务器应该自动启动,要检查它是否在运行,执行:

systemctl status mysql.service

使用MySQL

了解数据库和表

show databases;

在这里插入图片描述
SHOW DATABASES;返回可用数据库的一个列表。包含在这个列表中的可能是MySQL内部使用的数据库(如例子中的mysql和information_schema)

获取数据库内的表的列表

show tables;

在这里插入图片描述
SHOW TABLES;返回当前选择的数据库内可用表的列表

show 可以用来显示表列
显示指定表的列名信息

show columns from customers;

在这里插入图片描述
所支持的其他SHOW语句还有:
❑ SHOW STATUS,用于显示广泛的服务器状态信息;
❑ SHOW CREATE DATABASE和SHOW CREATE TABLE,分别用来显示创建特定数据库或表的MySQL语句;
❑ SHOW GRANTS,用来显示授予用户(所有用户或特定用户)的安全权限;
❑ SHOW ERRORS和SHOW WARNINGS,用来显示服务器错误或警告消息

检索数据

检索单个列

select prod_name from products;

在这里插入图片描述

检索多个列

在SELECT关键字后给出多个列名,列名之间必须以逗号分隔

 select prod_id,prod_name,prod_price from products;

在这里插入图片描述

检索所有的列

可以通过在实际列名的位置使用星号(*)通配符来达到

select * from products;

在这里插入图片描述

去重

 select distinct vend_id from products;

在这里插入图片描述

限制结果

SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为了返回第一行或前几行,可使用LIMIT子句
返回不多于5行

select prod_name from products limit 5;

在这里插入图片描述
可指定检索的开始行数和行数

select prod_name from products limit 5,5;

在这里插入图片描述

第一个数字表示的是开始位置,第二个为要检索的行数

行0 检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1将检索出第二行而不是第一行
在行数不够时 LIMIT中指定要检索的行数为检索的最大行数。如果没有足够的行(例如,给出LIMIT 10, 5,但只有13行), MySQL将只返回它能返回的那么多行

使用安全限定的表名

使用完全限定的名字来引用列(同时使用表名和列字)

select products.prod_name from products;

排序检索数据

排序数据

ORDER BY子句取一个或多个列的名字,据此对输出进行排序

select prod_name from products order by prod_name;

在这里插入图片描述
ORDER BY子句中使用的列将是为显示所选择的列

按多个列排序

为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列时所做的那样)

select prod_id,prod_price,prod_name from products order by prod_price, prod_name;

在这里插入图片描述

指定排序方向

按价格以降序排序产品(最贵的排在最前面)

select prod_id,prod_price,prod_name from products order by prod_price desc;

在这里插入图片描述
只对prod_price列指定DESC,对prod_name列不指定。因此,prod_price列以降序排序,而prod_name列(在每个价格内)仍然按标准的升序排序

select prod_id,prod_price,prod_name from products order by prod_price desc,prod_name;

在这里插入图片描述
ASC升序,默认是升序的
使用ORDER BY和LIMIT的组合,能够找出一个列中最高或最低的值

 select prod_price from products order by prod_price desc limit 1;

在这里插入图片描述

过滤数据

使用where子句

在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出

select prod_name,prod_price from products where prod_price = 2.50;

在这里插入图片描述

WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后,否则将会产生错误

where 字句操作符

检查单个值

select prod_name,prod_price from products where prod_name ='fuses';

在这里插入图片描述

检查WHERE prod_name=‘fuses’语句,它返回prod_name的值为Fuses的一行。MySQL在执行匹配时默认不区分大小写,所以fuses与Fuses匹配

列出价格小于10美元的所有产品:

select prod_name,prod_price from products where prod_price < 10;

在这里插入图片描述

不匹配检查

不是由供应商1003制造的所有产品:

select vend_id,prod_name from products where vend_id <> 1003;

另一种情况:

 select vend_id,prod_name from products where vend_id != 1003;

范围值检查

为了检查某个范围的值,可使用BETWEEN操作符,它需要两个值,即范围的开始值和结束值

select prod_name,prod_price from products where prod_price between 5 and 10;

在这里插入图片描述

空值判断

用来检查具有NULL值的列
无值返回空

 select prod_name from products where prod_price is null;

在这里插入图片描述
邮箱为空的顾客

select cust_id from customers where cust_email is null;

在这里插入图片描述

数据过滤

组合where子句

and 操作符

select prod_id,prod_price,prod_name from products where vend_id = 1003 and prod_price <= 10;

在这里插入图片描述
上述例子中使用了只包含一个关键字AND的语句,把两个过滤条件组合在一起。还可以添加多个过滤条件,每添加一条就要使用一个AND

or 操作符

select prod_name,prod_price from products where vend_id =1002 or vend_id =1003;

在这里插入图片描述
SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符,想要进行优先处理的话可以加上圆括号

in操作符

IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都括在圆括号中

select prod_name,prod_price from products where vend_id in (1002,1003) order by prod_name;

在这里插入图片描述

在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
IN操作符一般比OR操作符清单执行更快。
IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句

not操作符

NOT否定跟在它之后的条件,因此,MySQL不是匹配1002和1003的vend_id,而是匹配1002和1003之外供应商的vend_id

 select prod_name,prod_price from products where vend_id not in (1002,1003) order by prod_name;

在这里插入图片描述

用通配符进行过滤

like操作符

LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较

百分号(%)通配符

%表示任何字符出现任意次数
找出所有以词jet起头的产品

 select prod_id,prod_name from products where prod_name like 'jet%';

在这里插入图片描述

%告诉MySQL接受jet之后的任意字符,不管它有多少字符

通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。下面的例子使用两个通配符,它们位于模式的两端:

select prod_id,prod_name from products where prod_name like '%anvil%';

在这里插入图片描述
搜索模式’%anvil%’表示匹配任何位置包含文本anvil的值,而不论它之前或之后出现什么字符

通配符也可以出现在搜索模式的中间

select prod_name from products where prod_name like 's%e';

在这里插入图片描述

即使是WHERE prod_name LIKE '%’也不能匹配用值NULL作为产品名的行

下划线(_)通配符

只匹配单个字符而不是多个字符

select prod_id,prod_name from products where prod_name like '_ ton anvil';

在这里插入图片描述

使用正则表达式进行搜索

基本字符匹配

检索列prod_name包含文本1000的所有行:

 select prod_name from products where prod_name REGEXP '1000' order by prod_name;

在这里插入图片描述
REGEXP后所跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理

select prod_name from products where prod_name regexp '.000' order by prod_name;

在这里插入图片描述
正则表达式.000。.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符,因此,1000和2000都匹配且返回

在使用like匹配的时候,like会匹配整个列,如果被匹配的值在列中出现,like会找不到,相应的行也不会被返回,而regexp将会在列值中进行匹配,如果被匹配的文本在列值中出现,regexp将会找到它,相应的行将会被返回

进行or匹配

select prod_name from products where prod_name regexp '1000|2000' order by prod_name;

在这里插入图片描述
|为正则表达式的OR操作符。它表示匹配其中之一,因此1000和2000都匹配并返回

匹配几个字符之一

通过指定一组用[和]括起来的字符来完成,如下所示:

select prod_name from products where prod_name regexp '[123] Ton' order by prod_name;

在这里插入图片描述

匹配范围

集合可用来定义要匹配的一个或多个字符

select prod_name from products where prod_name regexp '[1-5] Ton' order by prod_name;

在这里插入图片描述
用正则表达式[1-5] Ton。[1-5]定义了一个范围,这个表达式意思是匹配1到5,因此返回3个匹配行。由于5 ton匹配,所以返回.5 ton

匹配特殊字符

为了匹配特殊字符,必须用\为前导。\-表示查找-, \.表示查找

select vend_name from vendors where vend_name regexp '\\.' order by vend_name;

在这里插入图片描述
\也用来引用元字符(具有特殊含义的字符)

\\f 换页
\\n 换行
\\r 回车
\\t 制表
\\v 纵向制表

匹配字符类

在这里插入图片描述

匹配多个实例

在这里插入图片描述

select prod_name from products where prod_name regexp '\\([0-9] sticks?\\)' order by prod_name;

在这里插入图片描述
\ (匹配), [0-9]匹配任意数字(这个例子中为1和5), sticks?匹配stick和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出现), \)匹配)。没有?,匹配stick和sticks会非常困难

匹配连在一起的4个数字

select prod_name from products where prod_name regexp '[[:digit:]]{4}' order by prod_name;

在这里插入图片描述
[:digit:]匹配任意数字,因而它为数字的一个集合。{4}确切地要求它前面的字符(任意数字)出现4次,所以[[:digit:]]{4}匹配连在一起的任意4位数字

定位符

目前为止的所有例子都是匹配一个串中任意位置的文本。为了匹配特定位置的文本,需要使用表中列出的定位符
在这里插入图片描述

 select prod_name from products where prod_name regexp '^[0-9\\.]' order by prod_name;

在这里插入图片描述
匹配串的开始。因此,[0-9\.]只在.或任意数字为串中第一个字符时才匹配它们。没有^,则还要多检索出4个别的行(那些中间有数字的行)

^的双重用途 ^有两种用法。在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处

创建计算字段

计算字段

存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。
如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。
城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打印程序却需要把它们作为一个恰当格式的字段检索出来。
列数据是大小写混合的,但报表程序需要把所有数据按大写表示出来。
物品订单表存储物品的价格和数量,但不需要存储每个物品的总价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
需要根据表数据进行总数、平均数计算或其他计算。

拼接字段

拼接(concatenate) 将值联结到一起构成单个值

 select concat(vend_name,'(',vend_country,')') from vendors order by vend_name;

在这里插入图片描述
Concat()拼接串,即把多个串连接起来形成一个较长的串。
Concat()需要一个或多个指定的串,各个串之间用逗号分隔。上面的SELECT语句连接以下4个元素:
❑ 存储在vend_name列中的名字;
❑ 包含一个空格和一个左圆括号的串;
❑ 存储在vend_country列中的国家;
❑ 包含一个右圆括号的串

select concat(rtrim(vend_name),'(',rtrim(vend_country),')') from vendors order by vend_name;

在这里插入图片描述
RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理

使用别名

别名(alias)是一个字段或值的替换名。别名用AS关键字赋予

select concat(rtrim(vend_name),'(',rtrim(vend_country),')') as vend_title from vendors ord
er by vend_name;

在这里插入图片描述

执行算术计算

orders表包含收到的所有订单,orderitems表包含每个订单中的各项物品。下面的SQL语句检索订单号20005中的所有物品:

select prod_id,quantity,item_price from orderitems where order_num =20005;

在这里插入图片描述
item_price列包含订单中每项物品的单价。如下汇总物品的价格(单价乘以订购数量):

select prod_id,quantity,item_price,quantity*item_price as expanded_price from orderitems where order_num = 20005;

在这里插入图片描述
输出中显示的expanded_price列为一个计算字段,此计算为quantity*item_price。客户机应用现在可以使用这个新计算列,就像使用其他列一样

使用数据处理函数

文本处理函数

select vend_name,upper(vend_name) as vend_name_upcase from vendors order by vend_name;

在这里插入图片描述
Upper()将文本转换为大写,因此本例子中每个供应商都列出两次,第一次为vendors表中存储的值,第二次作为列vend_name_upcase转换为大写
常用的文本处理函数
在这里插入图片描述

日期和时间处理函数

在这里插入图片描述

select cust_id,order_num from orders where order_date = '2005-09-01';

在这里插入图片描述
Date()函数。Date(order_date)指示MySQL仅提取列的日期部分

select cust_id,order_num from orders where Date(order_date) = '2005-09-01';

在这里插入图片描述
检索出2005年9月下的所有订单

 select cust_id,order_num from orders where Date(order_date) between '2005-09-01'and '2005-09-30';

在这里插入图片描述
还有另外一种办法(一种不需要记住每个月中有多少天或不需要操心闰年2月的办法):

select cust_id,order_num from orders where Year(order_date) = 2005 and Month(order_date) =9;

在这里插入图片描述
Year()是一个从日期(或日期时间)中返回年份的函数。类似,Month()从日期中返回月份。因此,WHERE Year(order_date)=2005 AND Month(order_date) = 9检索出order_date为2005年9月的所有行

数值处理函数

在这里插入图片描述

汇总数据

聚集函数

使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成。这种类型的检索例子有以下几种。
❑ 确定表中行数(或者满足某个条件或包含某个特定值的行数)。
❑ 获得表中行组的和。
❑ 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
在这里插入图片描述

AVG()函数

使用AVG()返回products表中所有产品的平均价格:

 select AVG(prod_price) as avg_price from products;

在这里插入图片描述
AVG()也可以用来确定特定列或行的平均值

 select AVG(prod_price) as avg_price from products where vend_id =1003;

在这里插入图片描述

count()函数

使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值
返回customers表中客户的总数:

select count(*) as num_cust from customers;

在这里插入图片描述
只对具有电子邮件地址的客户计数:

select count(cust_email) as num_cust from customers;

在这里插入图片描述

MAX()函数

select max(prod_price) as max_price from products;

在这里插入图片描述

MIN()函数

select min(prod_price) as min_price from products;

在这里插入图片描述

SUM()函数

SUM()用来返回指定列值的和(总计)
检索所订购物品的总数(所有quantity值之和):

 select sum(quantity) as items_orderd from orderitems where order_num = 20005;

在这里插入图片描述
SUM()也可以用来合计计算值。在下面的例子中,合计每项物品的item_price*quantity

select sum(item_price*quantity) as total_price from orderitems where order_num = 20005;

在这里插入图片描述

聚集不同值

平均值只考虑各个不同的价格:

select avg(distinct prod_price) as avg_price from products where vend_id = 1003;

在这里插入图片描述

组合聚集函数

select count(*) as num_items,min(prod_price) as price_min,max(prod_price) as price_max,avg(prod_price) as price_avg from products;

在这里插入图片描述

分组数据

数据分组

例子返回供应商1003提供的产品数目:

select count(*) as num_prods from products where vend_id =1003;

在这里插入图片描述

创建分组

分组是在SELECT语句的GROUP BY子句中建立的

select vend_id,count(*) as num_prods from products group by vend_id;

在这里插入图片描述
vend_id包含产品供应商的ID,num_prods为计算字段(用COUNT(*)函数建立)。GROUP BY子句指示MySQL按vend_id排序并分组数据。这导致对每个vend_id而不是整个表计算num_prods一次。从输出中可以看到,供应商1001有3个产品,供应商1002有2个产品,供应商1003有7个产品,而供应商1005有2个产品

GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。
❑ 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
❑ GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。
❑ 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。❑ 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
❑ GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

过滤分组

差别是WHERE过滤行,而HAVING过滤分组

 select cust_id,count(*) as orders from orders group by cust_id having count(*) >= 2;

在这里插入图片描述

 select vend_id,count(*) as num_prods from products where prod_price >=10 group by vend_id having count(*) >=2;

在这里插入图片描述

分组和排序

在这里插入图片描述
检索总计订单价格大于等于50的订单的订单号和总计订单价格:

select order_num,sum(quantity*item_price) as ordertotal from orderitems group by order_num having sum(quantity*item_price) >= 50;

在这里插入图片描述
为按总计订单价格排序输出,需要添加ORDER BY子句

select order_num,sum(quantity*item_price) as ordertotal from orderitems group by order_num having sum(quantity*item_price) >= 50 order by ordertotal;

在这里插入图片描述

select字句顺序

在这里插入图片描述

使用子查询

利用子查询进行过滤

 select order_num from orderitems where prod_id = 'TNT2';

在这里插入图片描述

select cust_id from orders where order_num in (20005,20007);

在这里插入图片描述

select cust_id from orders where order_num in (select order_num from orderitems where prod_id = 'TNT2');

在这里插入图片描述
在SELECT语句中,子查询总是从内向外处理。在处理上面的SELECT语句时,MySQL实际上执行了两个操作。首先,它执行下面的查询:
select order_num from orderitems where prod_id = ‘TNT2’
此查询返回两个订单号:20005和20007。然后,这两个值以IN操作符要求的逗号分隔的格式传递给外部查询的WHERE子句。外部查询变成:
select cust_id from orders where order_num in (20005,20007);
可以看到,输出是正确的并且与前面硬编码WHERE子句所返回的值相同

作为计算字段使用子查询

select count(*) as orders from orders where cust_id = 10001;

在这里插入图片描述
为了对每个客户执行COUNT( * )计算,应该将COUNT(*)作为一个子查询

select cust_name,cust_state,(select count(*) from orders where orders.cust_id = customers.cust_id) as orders from customers order by cust_name;

在这里插入图片描述
这条SELECT语句对customers表中每个客户返回3列:cust_name、cust_state和orders。orders是一个计算字段,它是由圆括号中的子查询建立的。该子查询对检索出的每个客户执行一次。在此例子中,该子查询执行了5次,因为检索出了5个客户

相关子查询

涉及外部查询的子查询

联结表

关系表

外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系

为什么要使用联结

联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行

创建联结

select vend_name,prod_name,prod_price from vendors,products where vendors.vend_id =products.vend_id order by vend_name,prod_name;

在这里插入图片描述
prod_name和prod_price)在一个表中,而另一个列(vend_name)在另一个表中
匹配的两个列以vendors.vend_id和products. vend_id指定。这里需要这种完全限定列名

完全限定列名 在引用的列可能出现二义性时,必须使用完全限定列名(用一个点分隔的表名和列名)。如果引用一个没有用表名限制的具有二义性的列名,MySQL将返回错误

where子句的重要性

笛卡儿积(cartesian product) 由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数

 select vend_name,prod_name,prod_price from vendors,products order by vend_name,prod_name;

内部联结

 select vend_name,prod_name,prod_price from vendors inner join products on vendors.vend_id = products.vend_id;

在这里插入图片描述
此语句中的SELECT与前面的SELECT语句相同,但FROM子句不同。这里,两个表之间的关系是FROM子句的组成部分,以INNER JOIN指定。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递给ON的实际条件与传递给WHERE的相同

联结多个表

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

select prod_name,vend_name,prod_price,quantity from orderitems,products,vendors where products.vend_id =vendors.vend_id and orderitems.prod_id =products.prod_id and order_num = 20005;

在这里插入图片描述

创建高级联结

使用表别名

别名不仅能用于WHERE子句,它还可以用于SELECT的列表、ORDER BY子句以及语句的其他部分

使用不同类型的联结

自联结

 select prod_id,prod_name from products where vend_id = (select vend_id from products where prod_id = 'DTNTR');

在这里插入图片描述

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

此查询中需要的两个表实际上是相同的表,因此products表在FROM子句中出现了两次。虽然这是完全合法的,但对products的引用具有二义性,因为MySQL不知道你引用的是products表中的哪个实例。为解决此问题,使用了表别名。products的第一次出现为别名p1,第二次出现为别名p2。现在可以将这些别名用作表名。例如,SELECT语句使用p1前缀明确地给出所需列的全名。如果不这样,MySQL将返回错误,因为分别存在两个名为prod_id、prod_name的列。MySQL不知道想要的是哪一个列(即使它们事实上是同一个列)。WHERE(通过匹配p1中的vend_id和p2中的vend_id)首先联结两个表,然后按第二个表中的prod_id过滤数据,返回所需的数据

自然联结

在这个例子中,通配符只对第一个表使用。所有其他列明确列出,所以没有重复的列被检索出来

select c.*,o.order_num,o.order_date,oi.prod_id,oi.quantity,oi.item_price from customers as c,orders as o,orderitems as oi where c.cust_id = o.cust_id and oi.order_num = o.order_num and prod_id ='FB';

在这里插入图片描述

外部联结

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

在这里插入图片描述
类似于上一章中所看到的内部联结,这条SELECT语句使用了关键字OUTER JOIN来指定联结的类型(而不是在WHERE子句中指定)。但是,与内部联结关联两个表中的行不同的是,外部联结还包括没有关联行的行。在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)。上面的例子使用LEFT OUTER JOIN从FROM子句的左边表(customers表)中选择所有行。为了从右边的表中选择所有行,应该使用RIGHT OUTER JOIN,如下例所示:

 select customers.cust_id,orders.order_num from customers right outer join orders on orders.cust_id = customers.cust_id;

在这里插入图片描述

使用带聚集函数的联结

如果要检索所有客户及每个客户所下的订单数,下面使用了COUNT()函数的代码可完成此工作:

select customers.cust_name,customers.cust_id,count(orders.order_num) as num_ord from customers inner join orders on customers.cust_id = orders.cust_id group by customers.cust_id;

在这里插入图片描述
此SELECT语句使用INNER JOIN将customers和orders表互相关联。GROUP BY子句按客户分组数据,因此,函数调用COUNT(orders.order_num)对每个客户的订单计数,将它作为num_ord返回

使用联结和联结条件

❑ 注意所使用的联结类型。一般我们使用内部联结,但使用外部联结也是有效的
❑ 保证使用正确的联结条件,否则将返回不正确的数据。
❑ 应该总是提供联结条件,否则会得出笛卡儿积。
❑ 在一个联结中可以包含多个表,甚至对于每个联结可以采用不同的联结类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们前,分别测试每个联结。这将使故障排除更为简单

组合查询

有两种基本情况,其中需要使用组合查询:
❑ 在单个查询中从不同的表返回类似结构的数据;
❑ 对单个表执行多个查询,按单个查询返回数据。

创建组合查询

可用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集

可用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集

假如需要价格小于等于5的所有物品的一个列表,而且还想包括供应商1001和1002生产的所有物品(不考虑价格)

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

union规则

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

包含或取消重复的行

UNION从查询结果集中自动去除了重复的行(换句话说,它的行为与单条SELECT语句中使用多个WHERE子句条件一样)。因为供应商1002生产的一种物品的价格也低于5,所以两条SELECT语句都返回该行。在使用UNION时,重复的行被自动取消。这是UNION的默认行为,但是如果需要,可以改变它。事实上,如果想返回所有匹配行,可使用UNION ALL而不是UNION

SELECT vend_id,prod_id,prod_priceFROM products
WHERE prod_price <= 5
UNION ALL
SELECT vend_id,prod_id,prod_priceFROM products
WHERE vend id IN (1001,1002):

对组合查询结果排序

SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句

SELECT vend_id,prod_id,prod_priceFROM products
WHERE prod_price <= 5
UNION
SELECT vend_idprod_id,prod_priceFROM products
WHERE vend_id IN (1001,1002)ORDER BY vend_id,prod_price;

这条UNION在最后一条SELECT语句后使用了ORDER BY子句。虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上MySQL将用它来排序所有SELECT语句返回的所有结果

全文本搜索

使用全文本搜索

为了进行全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。在对表列进行适当设计后,MySQL会自动进行所有的索引和重新索引。在索引之后,SELECT可与Match()和Against()一起使用以实际执行搜索

启用全文本搜索支持

一般在创建表时启用全文本搜索。CREATE TABLE语句接受FULLTEXT子句,它给出被索引列的一个逗号分隔的列表。下面的CREATE语句演示了FULLTEXT子句的使用:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值