zoukankan      html  css  js  c++  java
  • MySQL学习笔记(五)—— 子查询及联结

    子查询:    

         子查询,即嵌套在其他查询中的查询。例如我们有这样几个表,顾客表,订单表,商品表,我们想知道有哪些客户买了商品A,那么我们就需要先查看哪些订单里包含了商品A,然后根据订单查出是哪些客户。

    mysql> select cust_id from orders where order_num in (select order_num from orderitems where prod_id = '1');

    +---------+

    | cust_id |

    +---------+

    |    1001 |

    |    1002 |

    |    1003 |

    +---------+

    3 rows in set (0.01 sec)

         子查询总是从内向外操作,在上面的SQL中实际上是执行了两个操作,先把有产品1的订单找出来,然后在从这些订单中把客户号给找出来。

         在where子查询中可以嵌套多个子查询,可以通过查询编写出功能强大并且灵活的SQL语句,并且对于能嵌套的子查询的数目没有限制,不过在平时的日常使用中由于性能的限制,不能嵌套太多的子查询。

         在where子句中使用子查询,应该保证select语句具有与where子句中相同数目的列,通常子查询将返回单个列并且与单个列匹配,但是也可以使用多个列。

    作为计算字段使用子查询:

    例:需要显示customers表中每个客户的订单总数,订单与相应的客户id存储在orders表中。

    mysql> select cust_id,cust_name,(select count(*) from orders where orders.cust_id = customers.cust_id) as orders from customers order by cust_id;

    +---------+-----------+--------+

    | cust_id | cust_name | orders |

    +---------+-----------+--------+

    |    1001 | 张三      |      1 |

    |    1002 | 李四      |      2 |

    |    1003 | 王五      |      1 |

    |    1004 | 赵六      |      2 |

    |    1005 | 娄七      |      5 |

    |    1006 | 吴八      |      2 |

    +---------+-----------+--------+

    6 rows in set (0.00 sec)

        子查询中的where子句与前面使用的where子句稍有不同,select count(*) from orders where orders.cust_id = customers.cust_id,这条语句比较orders表中的cust_id和当前正从customers表中检索的cust_id,这种涉及到外部查询的子查询叫做相关子查询。如果我们不使用这种查询,即不适用完全限定的列名,那会出现什么样的结果。

    mysql> select cust_id,cust_name,(select count(*) from orders where cust_id = cust_id) as orders from customers order by cust_id;

    +---------+-----------+--------+

    | cust_id | cust_name | orders |

    +---------+-----------+--------+

    |    1001 | 张三      |     13 |

    |    1002 | 李四      |     13 |

    |    1003 | 王五      |     13 |

    |    1004 | 赵六      |     13 |

    |    1005 | 娄七      |     13 |

    |    1006 | 吴八      |     13 |

    +---------+-----------+--------+

    6 rows in set (0.00 sec)

         这样一来返回的都是orders表总的订单数,因为没有把两个表中的cust_id进行匹配,MySQL将认为是将orders表中的cust_id进行自身的匹配,这样每次都是返回的都是总订单数,因为每次都是匹配的,就跟没有增加where条件一样。

    联接表:

         首先了解下外键,主键之前已经学习过了,但是一张表的来区分每一行的唯一标示,那么外键是什么呢?从上面的例子可以看出,在顾客表中cust_id是customers的主键,orders表中主键是order_num,在存储订单的信息的同时,也存储了顾客ID,利用这个ID能从顾客表中查出该订单顾客的信息,那么这个cust_id又叫做orders的外键。

    外键:外键为某个表的一列,它包含了另一个表的主键值,定义了两个表之间的关系。

    创建联接:

    mysql> select cust_name,order_num from orders ,customers where customers.cust_id = orders.cust_id order by cust_name;

    +-----------+-----------+

    | cust_name | order_num |

    +-----------+-----------+

    | 吴八      |  10001012 |

    | 吴八      |  10001013 |

    | 娄七      |  10001009 |

    | 娄七      |  10001006 |

    | 娄七      |  10001011 |

    | 娄七      |  10001010 |

    | 娄七      |  10001007 |

    | 张三      |  10001001 |

    | 李四      |  10001003 |

    | 李四      |  10001002 |

    | 王五      |  10001004 |

    | 赵六      |  10001008 |

    | 赵六      |  10001005 |

    +-----------+-----------+

    13 rows in set (0.00 sec)

    笛卡尔积:由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目僵尸第一个表中的行数乘以第二个表中的行数。

    mysql> select cust_name,order_num from customers,orders;

    +-----------+-----------+

    | cust_name | order_num |

    +-----------+-----------+

    | 张三      |  10001001 |

    | 李四      |  10001001 |

    | 王五      |  10001001 |

    | 赵六      |  10001001 |

    | 娄七      |  10001001 |

    | 吴八      |  10001001 |

    | 张三      |  10001002 |

    | 李四      |  10001002 |

    | 王五      |  10001002 |

    | 赵六      |  10001002 |

    | 娄七      |  10001002 |

    | 吴八      |  10001002 |

    | 张三      |  10001003 |

    | 李四      |  10001003 |

    | 王五      |  10001003 |

    | 赵六      |  10001003 |

    | 娄七      |  10001003 |

    | 吴八      |  10001003 |

    | 张三      |  10001004 |

    | 李四      |  10001004 |

    | 王五      |  10001004 |

    | 赵六      |  10001004 |

    | 娄七      |  10001004 |

    | 吴八      |  10001004 |

    | 张三      |  10001005 |

    | 李四      |  10001005 |

    | 王五      |  10001005 |

    | 赵六      |  10001005 |

    | 娄七      |  10001005 |

    | 吴八      |  10001005 |

    | 张三      |  10001006 |

    | 李四      |  10001006 |

    | 王五      |  10001006 |

    | 赵六      |  10001006 |

    | 娄七      |  10001006 |

    | 吴八      |  10001006 |

    | 张三      |  10001007 |

    | 李四      |  10001007 |

    | 王五      |  10001007 |

    | 赵六      |  10001007 |

    | 娄七      |  10001007 |

    | 吴八      |  10001007 |

    | 张三      |  10001008 |

    | 李四      |  10001008 |

    | 王五      |  10001008 |

    | 赵六      |  10001008 |

    | 娄七      |  10001008 |

    | 吴八      |  10001008 |

    | 张三      |  10001009 |

    | 李四      |  10001009 |

    | 王五      |  10001009 |

    | 赵六      |  10001009 |

    | 娄七      |  10001009 |

    | 吴八      |  10001009 |

    | 张三      |  10001010 |

    | 李四      |  10001010 |

    | 王五      |  10001010 |

    | 赵六      |  10001010 |

    | 娄七      |  10001010 |

    | 吴八      |  10001010 |

    | 张三      |  10001011 |

    | 李四      |  10001011 |

    | 王五      |  10001011 |

    | 赵六      |  10001011 |

    | 娄七      |  10001011 |

    | 吴八      |  10001011 |

    | 张三      |  10001012 |

    | 李四      |  10001012 |

    | 王五      |  10001012 |

    | 赵六      |  10001012 |

    | 娄七      |  10001012 |

    | 吴八      |  10001012 |

    | 张三      |  10001013 |

    | 李四      |  10001013 |

    | 王五      |  10001013 |

    | 赵六      |  10001013 |

    | 娄七      |  10001013 |

    | 吴八      |  10001013 |

    +-----------+-----------+

    78 rows in set (0.00 sec)

    内部联结:inner join   on

    mysql> select cust_name,order_num from orders inner join customers on customers.cust_id = orders.cust_id order by cust_name;

    +-----------+-----------+

    | cust_name | order_num |

    +-----------+-----------+

    | 吴八      |  10001012 |

    | 吴八      |  10001013 |

    | 娄七      |  10001009 |

    | 娄七      |  10001006 |

    | 娄七      |  10001011 |

    | 娄七      |  10001010 |

    | 娄七      |  10001007 |

    | 张三      |  10001001 |

    | 李四      |  10001003 |

    | 李四      |  10001002 |

    | 王五      |  10001004 |

    | 赵六      |  10001008 |

    | 赵六      |  10001005 |

    +-----------+-----------+

    13 rows in set (0.00 sec)

    下一章就是高级联结,需要更细致深入的学习。。。。

    ---------------------------------------------

    Learning is endless......

    ---------------------------------------------

  • 相关阅读:
    Luogu P2391 白雪皑皑 && BZOJ 2054: 疯狂的馒头 并查集
    Luogu P3391 文艺平衡树(Splay or FHQ Treap)
    [笔记] 平衡树合集(Treap,Splay,替罪羊,FHQ Treap)
    P1353_[USACO08JAN]跑步Running 我死了。。。
    Luogu P1436 棋盘分割 暴力DP
    Luogu P1131 [ZJOI2007]时态同步 树形DP
    Luogu P1282 多米诺骨牌 DP。。背包?
    Luogu P1273 有线电视网 树形DP
    Luogu P1272 重建道路 树形DP
    Luogu P1156 垃圾陷阱 DP
  • 原文地址:https://www.cnblogs.com/dreamyu/p/6649149.html
Copyright © 2011-2022 走看看