第13-18章 联合&全文本

  • 第13-18章 联合&全文本
    • 13 分组数据
      • 创建分组
      • 过滤分组
      • 分组和排序
      • select子句顺序
    • 14 使用子查询
      • 使用子查询进行过滤
      • 作为计算字段使用子查询
    • 15 联结表
      • 用处
      • 外键
      • 创建联结
      • 内部联结
      • 联结多个表
      • 子查询和联结
    • 16 高级联结
      • 使用表别名
      • 不同类型联结
      • 带聚集函数的联结
      • 内联结和外联结区别
    • 17 组合查询
      • 关键字:UNION
      • 使用UNION
      • 规则
      • 包含或取消重复行
      • 排序
      • 注意:可以对不同表使用
    • 18全文本搜索
      • 数据库引擎
      • 使用
      • 查询扩展
      • 布尔文本搜索

第13-18章 联合&全文本

13 分组数据

创建分组

关键字:GROUP BY

SELECT vend_id,COUNT(*)AS num_prods

FROM products

GROUP BY vend_id:

对vend_id相同的进行分组,然后统计每一类的数目

注意

过滤分组

关键字:HAVING
HAVING支持所有WHERE的操作,不同处在于WHERE过滤行,HAVING过滤分组

SELECT cust_id, COUNT(*) AS orders

FROM orders

GROUP BY cust_id

HAVING COUNT(*) >= 2;

含义:选取订单大于2个的所有订单

分组和排序

两者不同,下面变表格第一点很重要,第二点注意每个选择都必须要在GROUP BY中使用

分组晚的输出不一定是拍好序的,需要利用ORDER BY再次调整

SELECT order_num,SUM(quantity*item_price)AS ordertotal

FROM orderitems

GROUP BY order_num

HAVING SUM(quantity*item_price)>=50ORDER BY ordertotal;

select子句顺序


14 使用子查询

使用子查询进行过滤

可以使用多个子查询来过滤,但是,注意缩进和分解,便于调试和阅读;

**注意:**使用SELECT和WHERE时保证列必须匹配

作为计算字段使用子查询

  • 此处的子查询会作为计算字段运行5次
  • WHERE子句用到了完全限定列名

子查询建议,逐层调试,到最后运行


15 联结表

用处

比如一个供应商提供多个商品,这些商品的供应商对应信息是相同的,因此需要联结,只用更新一个表中的信息,则所有的商品供应商信息都得到改变

外键

概念:某个表的一列,包含另一个表的主键值,定义了两个表的关系
作用:不要子查询

创建联结

SELECT vend_name ,prod_name, prod_price

FROM vendors, products

WHERE vend.vend_id = products.vend_id

ORDER BY vend_name, prod_name

分析

  • FROM两个表,表示联结这两个表;
  • WHERE限定很重要,没有的话,将返回第一个表的行数乘以第二个表行数个行,此处使用了完全限定列名

内部联结

SELECT vend_name ,prod_name, prod_price

FROM vendors INNER JOIN  products

ON vend.vend_id = products.vend_id

ORDER BY vend_name, prod_name

分析:实际效果与上述一样,但指定为内部联结,也称等值联结

联结多个表

分析

显示编号20005的4个订单;
每个订单含有prod_id编号,与products联结,找到对应4个产品,最后通过products中的vend_id和vend中匹配
最后返回4行,分别从三个表中得到的对应信息

注意:不要使用多个联结,性能降低很多

子查询和联结

效果两种一样,但联结要有效一些。

16 高级联结

使用表别名


注意:customers AS c此处使用表别名
作用:简化书写,但只在查询使用,不返回客户机

不同类型联结

  • 内部联结(等值联结):上一章
  • 自联结:
    分析:两次FROM products,因此需要别名,以区分;还可以用法子查询方法,但性能可能没有自联结好;
  • 自然联结
    分析:一般使用通配符;一般内部联结都是自然联结的
  • 外部联结:包含相关表中没有关联的行
    如下面代码,LEFT OUTER JOIN是不同的地方,需要制定LEFT或者RIGHT,left表示从左边表(customers)选择,反之则反

SELECT customers.cust_id, orders.order_num

FROM customers LEFT OUTER JOIN orders

ON customers.cust_id = orders.cust_id;

LEFT:RIGHT:
两者结果不一样

带聚集函数的联结

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;

COUNT为聚集函数,跨两个表使用,orders与customers两个位置互换关系不大;

内联结和外联结区别

外联结不必有內键和外键的关联,另外有LEFT和RIGHT关键字,可能导致结果出现空或者null;


17 组合查询

关键字:UNION

使用UNION

USE mysql_crash;

SELECT vend_id, prod_id, prod_price

FROM products

WHERE prod_price <= 5UNIONSELECT vend_id, prod_id, prod_price

FROM products

WHERE vend_id IN (1001, 1002);

结果:

分析:上述将两个结果输出到同一个结果,输出结果前4行为第一个查询的,后面为第二个。

上述可以用一个where语句来替换:

USE mysql_crash;

SELECT vend_id, prod_id, prod_price

FROM products

WHERE prod_price <= 5 OR vend_id IN (1001, 1002);

规则

包含或取消重复行

默认取消重复行,否则用 UNION ALL

USE mysql_crash;

SELECT vend_id, prod_id, prod_price

FROM products

WHERE prod_price <= 5UNION ALLSELECT vend_id, prod_id, prod_price

FROM products

WHERE vend_id IN (1001, 1002);

结果:

与上处比较这里多了一行重复的。

排序

只能用一条ORDER BY子句,在最后用,多个表时ORDER BY后跟多个条件

注意:可以对不同表使用


18全文本搜索

数据库引擎

MyISAM支持全文本搜索,InnoDB不支持。

使用

关键字:FULLTEXT(某表或者某列);
注意

应该导入数据完后再定义全文本搜索,效率提高
不区分大小写,否则用BINARY

搜索函数

Match():指定被搜索的列
Against():指定要使用的表达式

例子

USE mysql_crash;

SELECT note_text

FROM productnotes

WHERE Match(note_text)Against('rabbit');

输出

类似可以用LIKE来得到相同的结果:

SELECT note_text

FROM productnotes

WHERE note_text LIKE '%rabbit%';

优先等级返回情况

SELECT note_text,

      Match(note_text)Against('rabbit')AS rank

FROM productnotes;

没有关键词的等级为0,越靠前的数值越大;

查询扩展

与前面区别:WITH QUERY EXPANSION

SELECT note_text                    

FROM productnotes

WHERE MATCH(note_text) AGAINST('anvils' WITH QUERY EXPANSION);

输出

分析
第一行包含,因此排在第一位,第二行包含第一行新的关键词,因此被搜索

布尔文本搜索

关键字:IN BOOLEAN MODE
提供:要匹配的词,排斥的词,排列提示,表达式分组;
没有FULLTEXT索引也可以用,但比较慢

例子

SELECT note_text

FROM productnotes

WHERE Match(notetext)Against("heavy -rope*'IN BOOLEAN MODE);

分析
输出含有heavy,但不包含rope开头的词;

操作符

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值