zoukankan      html  css  js  c++  java
  • 表连接,子查询,exists

    表连接的本质

    数据库连接的本质:引用。

    create database xuanke;
    
    create table stu(sid int,sname varchar(20),sphonum char(11));
    create table tea(tid int,tname varchar(20),tphonum char); 
    create table course(cid int,cname varchar(20)); 
    create table xuanke1(sid int,tid int,cid int,xuefen int
    
    insert into stu values(1,'李三','110');
    insert into stu values(2,'王冲','120');
    insert into stu values(3,'安徽','130');
    insert into tea values(1113,'刘老师','1111');
    insert into tea values(1114,'王老师','2222');
    insert into course values(1,'linux');
    insert into course values(2,'mysql');
    insert into course values(3,'hadoop');
    
    insert into xuanke1 values(1,1113,2,2);
    insert into xuanke1 values(1,1114,2,4);
    insert into xuanke1 values(1,1113,3,6);
    insert into xuanke1 values(2,1113,2,2);
    insert into xuanke1 values(2,1114,1,2);
    insert into xuanke1 values(2,1113,3,2);

    要求:
    查找选择了哪些课程,课程名字,学分,老师。

    select s.sname,t.tname,c.cname,x.xuefen
    from stu s,tea t,course c,xuanke1 x  --》设置别名
    where s.sid=x.sid AND t.tid=x.tid AND c.cid=x.cid
    group by ...having...
    order by...

    1.首先确认我们需要的数据来自于哪些表
    2.看这些表中有什么关联关系
    3.填写select语句


    主键、外键

    主键:


      • 这个列里面的每一个值唯一的代表着这一行数据。
      • 值唯一,不能有重复,不能为空
      • 例:学生表的学号列。
    • 外键:
      • 这个列的所有数据来自于主表对应的主键。
      • eg:选课表里的学号列,是引用的学生表的主键列学生列。

    表连接的多种写法

    select s.sname,t.tname,c.cname,x.xuefen
    from stu s,tea t,course c,xuanke1 x  --》设置别名
    where s.sid=x.sid AND t.tid=x.tid AND c.cid=x.cid
    group by ...having...
    order by...

    select s.name,t.name,c.name,x.xuefen
    from stu s
    join xuanke x  --》表名
    on s.sid=x.xid  --》条件
    join tea t
    on x.tid=t.tid
    join course c
    on c.cid=x.cid

    join xuanke x  --》表名
    using(sid)  --》关联列的两列的名字必须一样!

    natural join xuanke x  --》表名

    外连接

    例:将所有学生以及他们的选课信息都列出来。
    所有学生信息、他们对应的选课信息

    左外连接

    “所有”两字落在主表上。 (主表里有的,外表不一定有–》例如:王五,没有选课)

    select s.name,x.xuefen
    from stu s
    left join xuanke x
    on s.sid=x.sid    (会显示空值)

    这里写图片描述

    右外连接

    将所有的选课信息以及对应的学生列出来
    (选课的学号列一定来自学生信息的学号列)
    (假设2号学生辍学了,但他曾经选过课)
    (即:选课信息里有的,但是学生信息里没有)
    right join
    on

    笛卡尔连接

    select s.name,t.name,c.name,x.xuefen
    from stu s,tea t,course c,xuanke x;

    注意:要避免笛卡尔连接!!因为会产生大量无效信息!
    这里写图片描述


    子查询

    无关子查询

    子查询:select里面还有select (- _ -)

    标量子查询(单行单列)

    例1:
    1.求1号球队的队长的编号

    select name from PLAYERS where PLAYERNO=(select PLAYERNO from TEAMS where TEAMNO=1

    例2:对于编号小于60的球员,得到他们加入俱乐部的年份和104号球员加入俱乐部的年份之间的差值。
    ==》

    select PLAYERNO,name,joined - (select joined from PLAYERS where PLAYERS=104from PLAYERS where PLAYERSNO<60

    [一个列减去一个值,返回的还是单行单列。]
    例3:得到27和44号球员的生日。

    selectselect birth_date from players where playerno=27);
    selectselect birth_date from players where playerno=44);

    例4:查询生日小于联盟队员编号为9999的球员生日的球员的编号和姓名。

    select playerno,NAME
    from players
    where birth_date<(
    select birth_date from players where leagueno='9999');

    行子查询(多列单行)

    查询和104号球员性别相同并且住在同一城市的球员的编号。

    select playerno
    from players
    where(sex,town)=(select sex,town from players where playerno=104and playerno<>104

    列子查询(单列多行)

    例:查询至少参加了一场比赛的球员的编号和姓名。

    select playerno,NAME
    from players
    where playerno INselect playerno from matches);

    例2:查询那些最老的球员的编号、姓名和生日。最老的球员指的是出生日期小于等于所有其它球员的球员

    SELECT  playerno,NAME,birth_date
    FROM  players
    WHERE  birth_date  <=ALL  ( 
    SELECT  birth_date
    FROM  players);

    PS:
    <=all() 小于最小的。

    any() 大于最小的。

    表子查询(多行多列)

    例:得到编号小于10的男性球员的编号。

    SELECT playerno
    FROM ( SELECT playerno,sex
              FROM players
              WHERE playerno < 10 ) AS player10
    WHERE sex='M'; 

    例2:得到编号大于10 而小于100,并且加入俱乐部的年份大于1980的男性球员的编号。
    第4层子查询得到编号大于10的所有球员的编号、性别和加入时间
    第3层子查询从上面得到编号小于10 的所有球员的编号、性别和加入时间
    第2层子查询从上面得到年份大于1980所有球员的编号、性别
    最外层子查询从上面得到男性球员的编号

    SELECT playerno
      FROM
      (SELECT  playerno, sex
         FROM
           (SELECT playerno, sex, joined
              FROM
                (SELECT playerno, sex, joined
                   FROM players
          WHERE playerno > 10) great10
        WHERE playerno < 100) less100
      WHERE joined > 1980) joined1980
    WHERE sex = ‘M’ ;

    {对子查询来说,先执行最最里面的子查询。}

    相关子查询

    相关子查询:子查询中使用到了外部查询的表中的任何列。先执行外部查询,然后执行子查询。
    相关子查询的执行步骤:
    1、先执行外部查询,得到的行叫做候选行
    2、使用某个候选行来执行子查询
    3、使用子查询的返回值来决定该候选行是出现在最终的结果集中还是被丢弃
    4、重复以上步骤2和3,将所有的候选行处理完毕,得到最终的结果

    相关子查询的where条件中一定有主查询的一个列。


    EXISTS和NOT EXISTS

    EXISTS操作符:
    该操作符专门判断子查询的结果集是否不为空:如果不为空则返回true,否则返回false
    例:得到那些至少支付了一次罚款的球员的名字和首字母 。

    SELECT NAME,initials
      FROM players p
      WHERE  EXISTS (
        SELECT 1
          FROM penalties
         WHERE playerno = p.playerno );

    例2:得到那些不是队长的球员的名字和首字母 。

    SELECT NAME,initials
      FROM players p
      WHERE NOT EXISTS(
        SELECT 1
          FROM teams
         WHERE playerno = p.playerno );
  • 相关阅读:
    .NET实现图片切割效果(带拖放、缩放效果)
    合成艺术字二 :使用的透明类以及所用的颜色选择器JS(完整事列源码)
    Ajax.net中的Web服务
    IE6和IE7共存方法 (转)
    sql取不重复多字段
    CSS完美兼容IE6/IE7/FF的通用方法
    发布事件.net框架程序设计
    const和readonly
    CSS网站实用技巧:wordwrap同wordbreak的区别
    FCKeditor 2.1.1在ASP.NET中的设置和使用(转)
  • 原文地址:https://www.cnblogs.com/lpeng94/p/12546477.html
Copyright © 2011-2022 走看看