建立高级联结
使用表别名
以前说到用AS能够建立别名,别名除了用于列名和计算字段外,SQL还容许给表名起别名,这样作有两个主要的理由:mysql
- 缩短SQL语句
- 容许在单条SELECT 语句中屡次使用相同的表
经过上面的语句,能够看到FROM子句中3个表所有都具备别名,customers AS c创建c做为customers的别名,在这个例子中,表别名只用于WHERE子句,可是表别名不只能用于WHERE子句,还可用于SELECT的列表,ORDER BY子句以及语句的其余部分;
使用不一样类型的联结
以前使用的都是内部联结或等值联结的简单联结;还有三种分别是自联结,天然联结,和外部联结;正则表达式
自联结
使用表别名的主要缘由之一是能在单条SELECT语句中不止一次引用相同的表;
这种解决办法,使用了子查询,内部的SELECT语句作了一个简单的检索,返回ID为DTNTR的vend_id,该ID用于外部查询的WHERE子句,以便检索出这个数据;
sql
这个是使用联结的相同查询,此查询须要的两个表其实是相同的表,所以products表在FROM子句中出现了两次,这是合法的,但对于products的引用是具备二义性的,由于MYSQL是不知道你引用的是products表中的那个实例;
为此,我使用了两个别名,p1,p2,而且根据实例进行联结查找表,按第二个表中的prod_id过滤数据,返回所需的数据
自联结一般做为外部语句来代替从相同表中检索数据时使用的子查询,最终结果都相同,但有时候处理联结远比处理子查询快的多;
数据库
天然联结
不管什么时候对表进行联结,应该至少有一个列出如今不止应该表中,标准的联结返回全部的数据,甚至会有屡次出现,天然联结排除屡次,使每一个列返回一次;
天然联结是这样一种联结,其中你只能选择那些惟一的列,这通常是经过对表使用通配符(SELECT *),对全部其余表的列使用明确的子集来完成的:
在这个例子中,通配符只对第一个表使用,全部其余列明确列出,因此没有重复的列检索出来;
安全
外部联结
许多联结将一个表中的行于另外一个表中的行相关联,有时会须要包含没有关联行的那些行;联结包含了那些在相关表中没有关联行的行,这种类型被称为外部联结
这条SELECT语句使用了OUTER JOIN来指定联结的类型,可是于内部联结关联两个表中行不一样的是,外部联结还包括没有关联行的行,在使用OUTER JOIN语法时,必须使用RIGHT 或LEFT关键字指定包含器全部行的表(RIGHT 指出的是OUTER JOIN右边的表,而LEFT指出的OUTER JOIN 左边的表)
函数
使用带汇集函数的联结
汇集函数用来汇总数据,汇集函数的全部例子只是从单个表汇总,这些函数也能够于联结一块儿使用:
此SELECT语句使用了INNER JOIN将customers和Orders表互相关联,GROUP BY子句按客户分组数据,函数调用COUT对每一个数据进行计数,做为num_ord返回
性能
汇集函数也能够方便的和其余联结一块儿使用
测试
使用联结和联结条件
联结及其使用的要点:spa
- 注意所使用的联结类型,通常使用内部联结,但使用外部联结也是有效的
- 保证使用正确的联结条件,不然返回不正确的数据
- 应该老是提供联结条件,不然会得出笛卡尔积
- 在一个联结中能够包含多个表,甚至对于每一个联结能够采用不一样的联结类型,虽然合法,通常颇有用,应该在使用前分别测试每一个联结
组合查询
组合查询
mysql容许执行多个查询,并将结果做为单个查询集返回,这些组合查询一般称为并(union)或复合查询(compound query)
有两种基本状况,其中须要使用组合查询:
3d
- 在单个查询中从不一样的表返回相似结构的数据
- 对单个表执行多个查询,按单个查询返回数据
建立组合查询
可用UNION操做符来组合数条SQL查询,利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集;
使用UNION
UNION的使用很简单,给出每条SELECT语句,在给条语句之间放上关键字UNION
结合这两条语句,以下:
这些语句由前面的两条SELECT语句组成,语句中用UNION关键字分隔,UNION指示Mysql执行两条SELECT语句,并把输出组合成当个查询结果集;
UNION规则
在使用UNION的几条规则:
- UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔,(所以,若是组合4条SELECT语句,要使用3个UNION关键字)
- UNION中的每一个查询必须包含相同的列,表达式或汇集函数(不过各个列不须要相同的次序列出)
- 列数据类型必须兼容:类型没必要彻底相同,但必须是DBMS能够隐含的转换类型,(列如,不一样的数值类型或不一样的日期类型)。
包含或取消重复的行
在使用UNION时,重复的行被自动取消,这是UNION的默认行为,若是须要,能够改变它,可使用UNION ALL而不是UNION。
使用UNION ALL,MYSQL不取消重复的行;
对组合查询结果排序
SELECT语句输出用ORDER BY子句排序,在使用UNION组合查询,只能使用一条ORDER BY子句,它必须出如今最后一条SLECT语句以后,对于结果集,不存在用一种方式排序一部分,所以不容许使用多条ORDER BY子句;
ORDERY BY子句虽然只出如今后面可是它排序了全部的SELECT 语句的数据;
全文本搜索
理解全文本搜索
虽然以前有LIKE关键字,它利用通配操做符匹配文本,使用LIKE,可以查找包含特殊值或部分值的行。
虽然搜索机制很是有用,但仍是有几个限制:
- 性能——通配符和正则表达式匹配一般要求MYSQL尝试匹配表中全部行,所以,因为被搜索行数不断地增长,这些搜索可能很是耗时
- 明确控制——使用通配符和正则表达式匹配。很难明确的控制匹配什么和不匹配什么;
- 智能化的结果——虽然基于通配符和正则表达式的搜索提供了很是灵活的搜索,但他们都不能提供一种智能化的选择结果的方法;
全部这些限制以及更多的限制均可以用全文本搜索来解决,在使用全文本搜索时,mysql不须要分别查看每一个行,也不须要分别分析和处理每一个词,mysql建立指定列中各词的应该索引,搜索能够针对这些词进行搜索;
使用全文本搜索
进行全文本搜索,要索引被搜索的列,要随着数据的改变而改变,MySQL会自动进行索引的索引和从新索引;
以后,SELECT可与MATCH()和Against()一块儿使用以实际执行搜索
启用全文本搜索支持
在建立表时启用全文本搜索,CREATE TABLE语句接受FULLTEXT子句,它给出被索引列的一个逗号分隔的列表;
CREATE TABLE:建立一个表;这里先看FULLTEXT子句,MYSQL根据子句FULLTEXT(note_text)的指示进行索引,这里FULLTEXT索引单个列,也能够指定多个列;
进行全文本搜索
索引以后,使用两个函数Match和Against执行全文本搜索,其中Match指定被搜索的列,Against指定要使用的搜索表达式;//除非咱们使用BINARY方式,不然全文本搜索不区分大小写
上述的搜索,也可以使用LIKE进行全文本搜索,但次序不一样;
在SELECT而不是WHERE子句中使用MATCH和Against,这使全部行都被返回,match和against用来创建一个计算列,此列包含全文本搜索计算出的等级值,等级由MYSQL根据行中词的数目,惟一词的数目,整个索引里面计算处理的;
使用查询扩展
查询扩展用来设法放宽所返回的全文本搜索结果的范围,这也是查询扩展的一项任务,在使用查询扩展时,MySQL对数据和索引进行两遍扫描来完成搜索:
- 首先:进行一个基本的全文本搜索,找出与搜索条件匹配的全部行‘
- 其次,MySQL检查这些匹配行并选择全部有用的词
- 再以后,MySQL再次进行全文本搜索,此次不只使用原来的条件,并且还使用全部有用的词;
布尔文本搜索
mysql支持全文本搜索的另外一种方式:称为布尔方式(boolean mode),以布尔方式。
- 要匹配的词
- 要排斥的词
- 排列的提高
- 表达式分组
- 另一些内容
此全文本搜索检索包含词heavy的全部行,其中使用了关键字IN BOOLEAN MODE,实际上没有指定布尔操做符,所以结果和没有指定的是相同;
插入数据
数据插入
INSERT 是用来插入行到数据库表的,插入能够用几种方式使用:
- 插入完整的行
- 插入行的一部分
- 插入多行
- 插入某些查询的结果
插入完整的行
将数据插入表中最简单的方式是使用INSERT语法:要求指定表名和被插入到新行中的值:
INSERT INTO Customers VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA' NULL, NULL);
INSERT语句通常不会产生输出,此语句是插入一个新客户到customers表中,存储到每一个表列中的数据再VALUES子句中给出,对每一个列必须提供一个值,上述的插入语句可能不够安全;
INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, cust_contact, cust_email) VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA' NULL, NULL);
虽然完成的是相同的工做,可是略显繁琐;可是够安全;
插入多个列
INSERT能够插入一行到一个表中,若是想要插入多行呢?
可使用多条INSERT语句,一次提交它们,每条语句用一个分号结束
INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, ) VALUES(NULL, 'Pep E. LaPew', '100 Main Street', 'Los Angeles', 'CA', '90046' 'USA'); INSERT INTO customers(cust_name, cust_address, cust_city, cust_state, cust_zipe, cust_country, ) VALUES('M.martian', '42 Galaxy way', 'New York', 'NY', '11213', 'USA');
插入检索出的数据
INSERT 还存在另一种形式,能够利用它将一条SELECT语句的结果插入表中,这检索所谓的INSERT SELECT,它是由INSERT语句和SELECT语句构成的;
INSERT INTO customers(cust_id, cust_contact, cust_email, cuts_name, cust_address, cust_city, cust_state, cust_zip, cust_country) SELECT cust_id, cust_cpmtact cust_email, cuts_name, cust_address, cust_city, cust_state, cust_zip, cust_country) FROM custenw;
使用INSERT SELECT 从custnew将数据导入其中;
更新和删除数据
更新数据
为了更新(修改)表中的数据,可使用UPDATE语句
- 更新表中特定行
- 更新表中全部行
UPDATE customers SET cust_email = 'elmer@fudd.com' WHERE cust_id=10005;
UPDATEE语句以where语句结束,高数MySQL更新到哪一行了;
删除数据
为了从一个表中删除数据,使用DELEATE语句,能够两种方式使用DELETE
从表中删除特定的行
从表中删除全部行
DELETE FROM customers, WHERE cust_id=10006;
删掉customers表中,cust_id=10006中的数据;