SQL必知必会 - 创建表的联结

目录

一、不同类型的联结

1 外联结

 2 内联结

二、用union联结

三、用where创建联结

1 用where简单联结

2 用where and的结合

四、 创建高级联结(用AS设置表别名)


inner join:2表值都存在

outer join:附表中值可能存在null的情况。

①A inner join B:取交集

②A left join B:取A全部,B没有对应的值,则为null

③A right join B:取B全部,A没有对应的值,则为null

④A full outer join B:取并集,彼此没有对应的值为null

上述4种的对应条件,在on后填写。

一、不同类型的联结

1 外联结

  • 用于联结没有关联的表。LEFT和RIGHT表示要联结的表,位于from表的左边还是右边
  • 外联结会设置主表,主表即以该表的数据为主,作为整体的主键。
外联结类型语句 补充说明
右外联结RIGHT OUTER JOIN右边的表 b 是主表,把右边关系中要舍弃的元组保留
左外联结LEFT OUTER JOIN b

以左边表a的列为主,取两列的交集,

对于不在右边列存在的取null

全外联结  FULL OUTER JOIN 检索所有行(包含两个表的不关联的行),把两个关系中要舍弃的元组保留

e.g1.  用左外联结,检索出所有顾客的顾客id和订单编号,包括没有订单的顾客

SELECT customers.cust_id,orders.order_num
       FROM customers
LEFT OUTER JOIN orders 
     ON customers.cust_id = orders.id;

 2 内联结

形式:

  • 即等值联结,是基于两个表的相等测试。等价于 JOIN 
  • inner join只会对非null值作join,并且两边都有才会匹配上 
  • 等值语法 INNER JOIN...ON  取两个表的交集,理解图如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LiK5aW95L2zVmFuZXNzYQ==,size_7,color_FFFFFF,t_70,g_se,x_16

e.g1. 上述同一个例子,用 INNER JOIN...ON来表述

SELECT vend_name,prod_name,prod_price
       FROM vendors
INNER  JOIN products
       ON vendors.vend_id = products.vend_id;

e.g2. 返回prod_id 为BR01 产品的所有顾客的电子邮件(Customers 表中的 cust_email)最内层的从 OrderItems 表返回 order_num,中间的从 Customers 表返回 cust_id。

select cust_email
from Orders
inner join OrderItems on Orders.order_num=OrderItems.order_num
inner join Customers on Orders.cust_id=Customers.cust_id
where prod_id='BR01'

 【示例结果】返回顾客email cust_email

 e.g3. 【同表数据源的内联结】可以只写join

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| recordDate    | date    |
| temperature   | int     |
+---------------+---------+
查找与之前(昨天的)日期相比温度更高的所有日期的 id 。

SELECT
    weather.id AS id
FROM
    weather
 JOIN
    weather w 
  ON DATEDIFF(weather.recordDate, w.recordDate) = 1
  AND weather.Temperature > w.Temperature;

二、用union联结

  • 用来合并两条sql的结果集
  • union--连接表,对行操作。join---连接表,对列操作

  • union--将两个表做行拼接,同时自动删除重复的行。
  • union all---将两个表做行拼接,保留重复的行。

e.g1. 表OrderItems包含字段prod_id代表产品id、quantity代表产品数量。将两个 SELECT 语句结合。一个 SELECT 语句过滤数量为100的行,另一个过滤 id 以BNBG开头的产品

select  prod_id,quantity
from OrderItems 
where prod_id like 'BNBG%'
union  
select  prod_id,quantity
from OrderItems 
where quantity=100;

e.g2. 从user_profile表中分别查看学校为山东大学或者性别为女性用户的device_id、gender、age和gpa数据,结果不去重

select  device_id, gender, age, gpa
from user_profile
where university='山东大学'

union all

select device_id, gender, age, gpa
from user_profile
where gender='male';

三、用where创建联结

1 用where简单联结

表现形式

指定要联结的所有表、联结它们的方式

e.g.输出vendors表中的经销商名称,products表中的商品名称和商品价格,其中两个表的关联是 经销商id是对应的

SELECT vend_name,prod_name,prod_price
FROM vendors,products
WHERE vendors.vend_id = products.vend_id;

注意要点

  • 多个表被引用时,需要使用完全列名 (用点隔开表名&列名)
  • 直接在from后面加上引用的多个表名
  • 作为过滤条件,将多个表中的行对应匹配
  • 要保证所有的联结,都有where子句

2 用where and的结合

① 自然联结

  • 作用:排除同个列多次返回出现,使每列都只返回一次
  • 即只选择那些唯一的列 → 只对一个表使用通配符 *  → 其他表作为子集,用明确的限定列名

e.g. 选择出customers表中购买了RGAN01产品的顾客的所有信息,以及orders表的订单编号和订单日期,orderitems表的item_price,联结关系是c表和o表的顾客id对应一致,oi表和o表的订单编号对应一致

SELECT c.*, o.order_num, o.order_date, 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_name = 'RGAN01';

② 联结多个表

  • 列出待联结的所有表 → 定义各个表的关系条件 → 用where和and联结各个条件
  • 可联结的表一般不限制数目

e.g1. 从orderitems,products,vendors表中,输出订单号为20007的产品名称,经销商名称,产品价格和数量。其中的限定条件是products和vendors表的经销商id一致,orderitems和products表的产品id一致

SELECT prod_name,vend_name,prod_price,quantity
FROM orderitems,products,vendors
WHERE products.vend_id = vendors.vend_id,
      AND orderitems.prod_id = products.vend_id
      AND order_num ='20007';

e.g2. 从customers表中返回 购买了产品RGAN01的顾客的姓名和联系方式,其中customers表和orders表的关联是顾客id对应,orderitems和orders的订单编号对应

SELECT cust_name,cust_contact
FROM customers,orders,orderitems
WHERE customers.cust_id = orders.cust_id
       AND orderitems.order_num = orders.order_num
       AND prod_name = 'RGAN01'; 

 e.g.3  给和jim jones同公司的顾客发邮件(先找出Jim Jones的公司 → 找出公司的所有顾客)表为customers,列为顾客id,顾客姓名和顾客的联系方式。

--联结的语句
SELECT c1.cust_id,c1.cust_name,c2.cust_contact
FROM customers AS c1,customers AS c2
WHERE c1.cust_name = c2.cust_name
      AND c2.cust_contact = 'jim jones';

--子查询语句
SELECT cust_id,cust_name,custt_contact
FROM customers
WHERE cust_name = (SELECT cust_name
                   FROM customers
                   WHERE cust_contact = 'jim jones');

四、 创建高级联结(用AS设置表别名)

  • 作用:缩短语句;允许一条select语句中多次引用同一张表
  • 注:表别名只在查询执行中使用,不会返回到客户端

e.g. 以同样的例子为例 从customers表中返回 购买了产品RGAN01的顾客的姓名和联系方式,其中customers表和orders表的关联是顾客id对应,orderitems和orders的订单编号对应

SELECT cust_name,cust_contact
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_name = 'RGAN01';

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值