MySQL必知必会读书笔记-6(组合查询UNION和全文本搜索)
1--使用UNION
使用UNION可以组合数条SQL查询,将他们的结果组合成单个结果集
例:查询价格小于等于5的所有物品的列表,并且包含供应商1001和1002的所有产品(包括价格大于5的物品)
这个操作涉及两条SELECT语句
1.检索出所有价格小于等于5的商品
SELECT vend_id, prod_name, prod_price FROM products WHERE prod_price <= 5
2.检索出所有由1001和1002生产的商品
SELECT vend_id, prod_name, prod_price FROM products WHERE vend_id IN (1001, 1002)
3.使用UNION将他们组合起来
SELECT vend_id, prod_name, prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id, prod_name, prod_price FROM products WHERE vend_id IN (1001, 1002)
如果使用多条WHERE字句的话这样实现,结果相同
SELECT vend_id, prod_name, prod_price FROM products WHERE prod_price <= 5 OR vend_id IN (1001, 1002)
2--UNION的使用规则
3--UNION对重复行的操作
上面的例子,前两次检索分别输出了四行和五行,联合检索后变成了八行,说明UNION操作自动取消了
重复行(WHERE操作也是如此)。如果想检索出所有行,使用UNION ALL
SELECT vend_id, prod_name, prod_price FROM products WHERE prod_price <= 5 UNION ALL SELECT vend_id, prod_name, prod_price FROM products WHERE vend_id IN (1001, 1002)
3--UNION与WHERE
4--组合查询的排序
SELECT vend_id, prod_name, prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id, prod_name, prod_price FROM products WHERE vend_id IN (1001, 1002) ORDER BY vend_id, prod_price
使用UNION查询的时候只能使用一次ORDER BY子句,只能对结果集进行排序,
不能只排一部分
5--全文本搜索
MyISAM支持,InnoDB不支持
通过通配符和正则表达式可以进行文本的搜索,但他们都有一些限制
这些限制可以用全文本搜索来解决
6--启用全文本搜索
需要在创建表的时候启用全文本搜索
定义之后由MySQL自动维护索引。
7--进行全文本搜索
定义索引后,使用Match()和Against()执行全文本搜索
SELECT note_text FROM productnotes WHERE MATCH(note_text) AGAINST('rabbit')
当然上面的例子完全可以通配符实现,但是全文本搜索的好处是对结果排序,因此你想要的行总是排在第一位
演示一下:
我们用Match和against来建立一个计算列,这个列中显示所有行与结果的匹配度,根据上面的搜索结果与这里的进行对比
可以看出来全文本搜索将最相关的结果排在前面
SELECT note_text, MATCH(note_text) AGAINST('rabbit') AS rank FROM productnotes
8--使用查询扩展
假设你要查询所有提到anvils的注释,只有一个注释包含词anvils。
但同时你还想找其他可能与你的搜索结果相关的行,即使他们不包含关键字
例子:进行一个简单的全文本搜索,没有查询扩展
SELECT note_text FROM productnotes WHERE MATCH(note_text) AGAINST('anvils')
使用查询扩展
SELECT note_text FROM productnotes WHERE MATCH(note_text) AGAINST('anvils'WITH QUERY EXPANSION)
9--布尔文本搜索
以布尔方式可以提供如下内容的细节
例子:匹配出包含heavy但是不包含任意以rope开始的词的行
1.只搜索heavy
SELECT note_text FROM productnotes WHERE MATCH(note_text) AGAINST('heavy')
2.增加布尔条件
SELECT note_text FROM productnotes WHERE MATCH(note_text) AGAINST('heavy -rope*'IN BOOLEAN MODE)
全文本布尔操作符
10--全文本搜索使用说明