• SQL的多表操作


    多表更新

    假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price;另外一张表是ProductPrice表,我们要将ProductPrice表中的价格字段Price更新为Price表中价格字段的80%。 

    在Mysql中我们有几种手段可以做到这一点,一种是update table1 t1, table2 ts ...的方式:

    UPDATE product p, productPrice pp 
    SET pp.price = pp.price * 0.8 
    WHERE p.productId = pp.productId 
    AND p.dateCreated < '2004-01-01' 

    另外一种方法是使用inner join然后更新: 

    代码如下:

    UPDATE product p 
    INNER JOIN productPrice pp 
    ON p.productId = pp.productId 
    SET pp.price = pp.price * 0.8 
    WHERE p.dateCreated < '2004-01-01' 

    另外我们也可以使用left outer join来做多表update,比方说如果ProductPrice表中没有产品价格记录的话,将Product表的isDeleted字段置为1,如下sql语句: 

    代码如下:

    UPDATE product p 
    LEFT JOIN productPrice pp 
    ON p.productId = pp.productId 
    SET p.deleted = 1 
    WHERE pp.productId IS null 

    另外,上面的几个例子都是两张表之间做关联,但是只更新一张表中的记录,其实是可以同时更新两张表的,如下sql: 

    代码如下:

    UPDATE product p 
    INNER JOIN productPrice pp 
    ON p.productId = pp.productId 
    SET pp.price = pp.price * 0.8, 
    p.dateUpdate = CURDATE() 
    WHERE p.dateCreated < '2004-01-01' 


    两张表做关联,更新了ProductPrice表的price字段和Product表字段的dateUpdate两个字段。

    ---------------------------------------------------------------------------------华丽分割线---------------------------------------------------------------------------------

    多表查询

    新建两张表:

    表1:student      表2:course

      SQL多表连接查询(详细实例)_新客网      SQL多表连接查询(详细实例)_新客网

    (此时这样建表只是为了演示连接SQL语句,当然实际开发中我们不会这样建表,实际开发中这两个表会有自己不同的主键。)

    一、外连接

    外连接可分为:左连接、右连接、完全外连接。

    1、左连接  left join 或 left outer join

    SQL语句:select * from student left join course on student.ID=course.ID

    执行结果:SQL多表连接查询(详细实例)_新客网左外连接包含left join左表所有行,如果左表中某行在右表没有匹配,则结果中对应行右表的部分全部为空(NULL).

    注:此时我们不能说结果的行数等于左表数据的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系。

    2、右连接  right join 或 right outer join

    SQL语句:select * from student right join course on student.ID=course.ID

    执行结果:SQL多表连接查询(详细实例)_新客网右外连接包含right join右表所有行,如果左表中某行在右表没有匹配,则结果中对应左表的部分全部为空(NULL)。

    注:同样此时我们不能说结果的行数等于右表的行数。当然此处查询结果的行数等于左表数据的行数,因为左右两表此时为一对一关系。

    3、完全外连接  full join 或 full outer join

    SQL语句:select * from student full join course on student.ID=course.ID

    执行结果:SQL多表连接查询(详细实例)_新客网完全外连接包含full join左右两表中所有的行,如果右表中某行在左表中没有匹配,则结果中对应行右表的部分全部为空(NULL),如果左表中某行在右表中没有匹配,则结果中对应行左表的部分全部为空(NULL)。

    二、内连接  join 或 inner join

    SQL语句:select * from student inner join course on student.ID=course.ID

    执行结果:SQL多表连接查询(详细实例)_新客网inner join 是比较运算符,只返回符合条件的行。此时相当于:select * from student,course where student.ID=course.ID

    三、交叉连接 cross join

    1.概念:没有 WHERE 子句的交叉联接将产生连接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。

    SQL语句:select * from student cross join course

    执行结果:SQL多表连接查询(详细实例)_新客网如果我们在此时给这条SQL加上WHERE子句的时候比如SQL:select * from student cross join course where student.ID=course.ID

    此时将返回符合条件的结果集,结果和inner join所示执行结果一样。

    四、两表关系为一对多,多对一或多对多时的连接语句

    当然上面两表为一对一关系,那么如果表A和表B为一对多、多对一或多对多的时候,我们又该如何写连接SQL语句呢?

    其实两表一对多的SQL语句和一对一的SQL语句的写法都差不多,只是查询的结果不一样,当然两表也要略有改动。

    比如表1的列可以改为:

    Sno Name Cno

    表2的列可以改为:

    Cno CName

    这样两表就可以写一对多和多对一的SQL语句了,写法和上面的一对一SQL语句一样。

    下面介绍一下当两表为多对多的时候我们该如何建表以及些SQL语句。

    新建三表:

    表A:  student 截图如下:     表B:  course 截图如下:   表C:  student_course 截图如下:

        SQL多表连接查询(详细实例)_新客网            SQL多表连接查询(详细实例)_新客网      SQL多表连接查询(详细实例)_新客网

    一个学生可以选择多门课程,一门课程可以被多个学生选择,因此学生表student和课程表course之间是多对多的关系。

    当两表为多对多关系的时候,我们需要建立一个中间表student_course,中间表至少要有两表的主键,当然还可以有别的内容。

    SQL语句:select s.Name,C.Cname from student_course as sc left join student as s on s.Sno=sc.Sno left join course as c on c.Cno=sc.Cno

    执行结果:SQL多表连接查询(详细实例)_新客网此条SQL执行的结果是学生选课的情况。

    ---------------------------------------------------------------------------------华丽分割线---------------------------------------------------------------------------------

    distinct的特殊用法:select  count(*) from (select distinct cdkey from tbl_alipay) s;

    distinct的另一种方法:

    select *, count(distinct name) from table group by name

    结果:

       id name count(distinct name)
       1 a 1
       2 b 1
       3 c 1

    最后一项是多余的,不用管就行了,目的达到

    group by 必须放在 order by 和 limit之前,不然会报错

    引用自:http://www.jb51.net/article/24717.htm

  • 相关阅读:
    h5自定义播放器得实现原理
    this a sao
    Winform(C#)输入完毕后,按Enter键触发Button事件
    解析xml文件,C# 获取所有节点的属性值
    xml节点和元素的关系
    C#中DataGridView控件使用大全
    Linq To Xml操作XML增删改查
    winform中如何选中datagridview中的一行数据双击后跳转并将其显示在另一个页面的datagirdview中
    Winform中的dataGridView添加自动编号
    C# winform 主界面打开并关闭登录界面
  • 原文地址:https://www.cnblogs.com/showonce/p/5947768.html
Copyright © 2020-2023  润新知