zoukankan      html  css  js  c++  java
  • MySQL学习笔记(六)—— MySQL自连接

         有的时候我们需要对同一表中的数据进行多次检索,这个时候我们可以使用之前学习过的子查询,先查询出需要的数据,再进行一次检索。

    例如:一张products表,有产品id,供应商id(vend_id),产品名称等等.  

    mysql> select * from products;

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

    | prod_id | vend_id | prod_name | prod_price | prod_desc |

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

    |       1 |  550001 | 苹果      |         30 | NULL      |

    |       2 |  550002 | 橘子      |         40 | NULL      |

    |       3 |  550003 | 香蕉      |         50 | NULL      |

    |       4 |  550004 | 甜梨      |         60 | NULL      |

    |       6 |  550001 | 柿子      |         50 | NULL      |

    |       7 |  550001 | 椰子      |         44 | NULL      |

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

    问题:我们了解到苹果这个产品质量存在问题,因此想看下苹果的供应商的其他产品是否存在问题.

    分析:我们需要先获取苹果的vend_id,通过这个id获取其他的产品.

    方法一: 使用子查询

    mysql> select * from products where vend_id = (select vend_id from products where prod_name = '苹果');

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

    | prod_id | vend_id | prod_name | prod_price | prod_desc |

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

    |       1 |  550001 | 苹果      |         30 | NULL      |

    |       6 |  550001 | 柿子      |         50 | NULL      |

    |       7 |  550001 | 椰子      |         44 | NULL      |

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

    3 rows in set (0.00 sec)

    方法二:我们使用自联结,将vend_id与苹果这个产品vend_id相等的产品联结检索出来.

    首先我们先引入一个新概念,表别名.  我们在进行表操作的时候为了方便可以给表起个别名,例如:

    select * from products as prod where prod.prod_id = 1;

    了解了这个我们再看下自联结,还是那个问题,使用自联结:

    mysql> select p1.prod_id,p1.prod_name from products as p1,products as p2

        -> where p1.vend_id = p2.vend_id and p2.prod_name = '苹果';

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

    | prod_id | prod_name |

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

    |       1 | 苹果      |

    |       6 | 柿子      |

    |       7 | 椰子      |

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

    3 rows in set (0.00 sec)

    分析:我们将products表看成是两个表,一个表中的数据存储的是prod_name为苹果的数据,另一个表中存储的是其他的水果数据,我们将两个表的数据进行联结(其实就是联结的products这一张表)

    我们再倒着看,先看sql语句:

    select p1.prod_id,p1.prod_name from products as p1,products as p2

        where p1.vend_id = p2.vend_id and p2.prod_name = '苹果';

     这个语句说明的意思是查找p1表中的id和name,条件是p1的vend_id和p2的vend_id相等,同时p2的prod_name是苹果,那就是说先查看name为苹果的vend_id,把与苹果vend_id相等的数据找出来.

         使用自联结而不是使用子查询的原因是,自联结的处理速度和性能更优于子查询.

    再举个面试的例子,前几天刚遇到的:

    有一张学生成绩表,有学生姓名,分数,科目,找出小明分数大于80分的科目中谁的分数最高.

    方法一:

    select * from student where student.class = (select student.class from student where student.name = '小明'  and student.score >80 ) order by student.score limit 1;

    方法二:

    select s1.name,s1.score from student as s1,student as s2 where s1.class = s2.calss and s2.name = '小明' and s2.score >80;

  • 相关阅读:
    等差子序列(sequence)
    威士忌(whiskey)
    图论:2-SAT模板
    poj2723-Get Luffy Out
    acdream1412:2-3 trees 组合数dp
    hdu3849-By Recognizing These Guys, We Find Social Networks Useful:双连通分量
    ZOJ2317-Nice Patterns Strike Back:矩阵快速幂,高精度
    ZOJ3519-Beautiful People:最长上升子序列的变形
    hdu2460-Network:边的双连通分量
    hdu4405:概率dp
  • 原文地址:https://www.cnblogs.com/dreamyu/p/6804543.html
Copyright © 2011-2022 走看看