查询
子查询
将上一次查询的结果作为下一次查询的条件。
SELECT column FROM table1 WHERE column2 IN (SELECT column2 FROM table2 WHERE column3 = 'xxx')
列必须匹配
在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。
作为计算字段使用子查询
SELECT column1, (SELECT COUNT(*) FROM table1 WHERE table1.id = table2.id) AS column2 FROM table2
相关子查询:涉及外部查询的子查询。
任何时候只要列名可能有多义性,就必须使用这种语法。
联结表
连表的意义
- 节省存储的时间,节省存储空间
- 改动信息只需要改动一次
- 保证每次输入该数据的方式都相同,保证数据一致
这个因素也是关系数据库设计的基础。
可伸缩性:能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。
主键和外键
- 主键:具有唯一标识的列
- 外键:某一列,包含另一个表的主键,定义两个表的关系。
使用WHERE创建联结
SELECT column1, column2 FROM table1, table2 WHERE table1.id = table2.id
完全限定列名
在引用的列可能出现二义性时,必须使用完全限定列名(table.column)
笛卡尔积(叉联结)
当没有限定WHERE条件时,返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘 以第二个表中的行数。
SELECT column1, column2 FROM table1, table2
内部联结(INNER JOIN xxx ON xxx)
联结条件用特定的ON子句而不是WHERE 子句给出。传递给ON的实际条件与传递给WHERE的相同。
SELECT column1, column2 FROM table1 INNER JOIN table2 ON table1.id = table2.id
联结多个表
SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。
不要联结不必要的表。联结的表越多,性能下降越厉害。
高级联结
使用表别名
- 缩短SQL语句;
- 允许在单条SELECT语句中多次使用相同的表。
SELECT column1, column2 FROM table1 AS a, table2 AS b WHERE a.id = b.id;
(自联结)
SELECT column1, column2 FROM table AS a, table AS b WHERE a.id = b.id;
用自联结而不用子查询,处理联结远比处理子查询快得多。
自然联结
标准的联结返回所有数据,甚至相同的列多次出现。自然联结排除多次出现,使每个列只返回一次。
迄今为止我们建立的每个内部联结都是自然联结,很可能我们永远都不会用到不是自然联结的内部联结。
外部联结(LEFT/RIGHT OUTER JOIN)
左外部联结LEFT OUTER JOIN
和右外部联结RIGHT OUTER JOIN
。
使用LEFT OUTER JOIN
从FROM 子句的左边表中选择所有行,RIGHT
同理。
带聚合函数的联结
聚集函数用来汇总数据,这些函数也可以与联结一起使用。
组合查询(UNION)
MySQL允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这种组合查询称为并(或者复合)查询。
两种使用场景:
- 在单个查询中从不同的表返回类似结构的数据
- 对单个表执行多个查询,按单个查询返回数据
比如:SELECT colum1, column2 FROM table WHERE id = '5' UNION SELECT colum1, column2 FROM table WHERE name = 'xxx'
📢 注意
- UNION必须由两条或两条以上的SELECT语句组成,每两个语句之间用关键字UNION分隔
- UNION中的每个查询必须包含相同的列、表达式或聚集函数
- 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型
自动去重
UNION从查询结果集中会默认自动去除了重复的行,如果需要,可以改变它。事实上,如果 想返回所有匹配行,可使用UNION ALL
而不是UNION
。
对查询结果进行排序
在用UNION组合查询时,只 能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。不允许使用多条ORDER BY子句。
全文本搜索
对比之前的搜索机制(通配符和正则表达式)
- 会尝试匹配所有行,可能非常耗时
- 无法明确控制匹配什么和不匹配什么
- 匹配结果不够智能,无法按照可能更好的匹配来排列结果。
启用全文本搜索支持
在建表的时候启用全文本搜索(FULLTEXT
)。可以指定多列。
CREATE TABLE table
(
id int NOT NULL AUTO_INCREMENT,
column1 char(10) NOT NULL,
PRIMARY KEY(id),
FULLTEXT(column1)
)
也可以在建表后再指定。
不要再导入数据时使用FULLTEXT,先导入所有数据,再定义FULLTEXT
进行全文本搜索
在索引之后,使用两个函数Match()和Against()执行全文本搜索,其中Match()
指定被搜索的列,Against()
指定要使用的搜索表达式。
SELECT column, Match(column) Against('text') AS rank FROM table