数据库学习笔记(三)2017.9.16

写在前面:本篇博客大部分内容参考数据库系统概念(本科教学版)第三章(第三章部分的多表操作没有在此处讲,准备挪到第四章再一起讨论)


SELECT * 与 SELECT 全字段 的执 行效率是有差别的

  • 数据库在具体执行 SELECT * 的时候可以这样理解:首先把 * 替换成对应表的全字段序列,再执行。故在执行的的时候 SELECT * 的效率是会更低的
  • 事实上 SELECT * 也是典型的低效语句
  • 故在实际应用过程中应该尽量避免使用 SELECT *

where子句 andornot的优先级顺序

  • or < and < not (not的优先级最高)
    • 例如:我们要实现“年龄小于16或大于18,并且分数不小于60的所有学生”
    • 于是写出了 </br>
      where age > 18
      or age < 16  
      and not score < 60
      
    • 上面的语句实际表示的是: 分数不小于60并且年龄小于16,或者年龄大于18
  • 实际使用的时候不要依赖于它们的优先级顺序!!
    • 上面的需求可用下面的语句实现:</br>
      where (age > 18 or age < 16)
      and score >= 60
      

SQL 附加的基本运算

  • 更名运算 as

    • stu_name age score
      stu1 18 98

      首先存在如上表结构

    • 需要事先申明的是,这里所说的更名并不是实际更改数据库中的表结构,更改只是在执行查询操作的过程中得到的结果视图

    • as 关键字可用于SELECT语句中给字段更名

      • 执行如下语句:
        SELECT stu_name as student_name, age, score
        FROM Student
        
        得到如下结果
      • student_name age score
        stu1 18 98
    • as 关键字可用于FROM语句中给表更名

      • as可以把一个长的关系名替换成短的,这样在查询语句的其他地方用到这个关系名的时候就会方便不少
      • 执行如下语句
        -- 下面两个语句实现的效果是一样的,但是显然第二种比较简洁
        
        SELECT Student.stu_name, Student.age
        FROM Student
        
        SELECT S.stu_name, S.age
        FROM Student as S
        
      • 还有一种情况需要用as修改表名,就是需要比较同一个关系中的元组的时候,必须要用别名,要不然无法区分
        • stu_name age score
          Sunny 18 98
          Robbin 18 96
          James 19 67
          Jane 17 82
          现在表中有如上数据
        • 我们需要查询表中所有比Jane的成绩高的学生的名字
        • 则可以用下面的语句实现:
          SELECT T.stu_name
          FROM Student as T, Student as S
          WHERE T.score > S.score and S.stu_name = 'Jane'
          
          得到以下结果
        • stu_name
          Sunny
          Robbin
    • 大多数数据库中可以用空格替代as

      -- 下面两个语句是等价的(在Mysql数据库上测试)
      SELECT T.stu_name
      FROM Student as T, Student as S 
      WHERE T.score > S.score and S.stu_name = 'Jane'
      
      SELECT T.stu_name
      FROM Student T, Student S 
      WHERE T.score > S.score and S.stu_name = 'Jane'
      
    • 注意:Oracle数据库更改表的别名不能用 as(但是改字段的别名是可以用as的), 只能用空格,要不然会报错(比如上面的两个语句在大多数数据库执行都是可以通过而且结果一致的,但是在Oracle数据库第一条语句就不会过)**

    • 如果别名中带空格,则别名需要用双引号引起来(因为空格也是可以替代as的,所以如果别名中含有空格而不做处理,可能会导致数据库无法解析这条语句)

      • 首先看下面这条语句
        -- 下面这条语句想给Student表起一个别名,叫做 Student Info, 执行是会失败的
        SELECT Student Info.stu_name
        FROM Student as Student Info
        
      • 正确的操作应该是这样的
        SELECT "Student Info".stu_name
        FROM Student as "Student Info"
        
  • 字符串的拼接运算

    • 不用数据库采用不同的运算符,常见的有 ||+
      • stu_name age score
        Sunny 18 98
        Robbin 18 96
        James 19 67
        Jane 17 82
        现在表中有如上数据
      • 执行下面的语句(笔者是在Mysql下测试的,Mysql的字符串拼接是用connect函数实现的,所以略有不同)
        SELECT S.stu_name, concat('name: ', S.stu_name) as info
        FROM Student as S   
        
        得到如下结果
      • stu_name info
        Sunny name: Sunny
        Robbin name: Robbin
        James name: James
        Jane name: Jane
    • 对于null值的处理,不同的数据库采取的处理不同
      • Oracle会直接忽略空值,而DB2会使整体为null
      • 下面在Mysql中测试与空值拼接,结果是会使整体为null
        • 执行以下语句
          SELECT S.stu_name, concat('name: ', S.stu_name, NULL ) as info
          FROM Student as S
          
          结果如下
        • stu_name info
          Sunny null
          Robbin null
          James null
          Jane null
    • 可以与字符串常量拼接
      • sql里面就用一对单引号包含一个字符串表示字符串常量,如'name: '
      • 上面的例子里面就用到了与字符串常量拼接,这里就不再赘述了
    • 如果字符串常量里面需要包含单引号,可以用另一个单引号来转义
      • 比如执行下面的语句
        # 下面的字符串常量中出现了四个单引号,其中首位两个是用来标示这个是一个字符串常量,第二个单引号是用来转义第三个单引号
        SELECT S.stu_name, concat('I''m ', S.stu_name) as info
        FROM Student as S   
        
        结果如下:
      • stu_name info
        Sunny I'm Sunny
        Robbin I'm Robbin
        James I'm James
        Jane I'm Jane
  • 函数

    • 其实函数每个数据库都有各自的实现,种类和功能不尽相同
    • 比如上面的connect函数是Mysql中的一个函数
    • upper(s)和lower(s)函数是用来将字符串全部变成大写/小写的函数
  • 模糊匹配(like)

    • 通配符(具体到某个具体的数据库可能还会有功能更强大的通配符,这里只讨论比较通用的两个)
      • % ==>匹配任意长度的字符串(字符串的长度也可以是0)
      • _ ==>匹配一个字符
      • 举个栗子:
        -- 下面的语句标示查询条件是第三个字符是A的stu_name
        WHERE stu_name LIKE '__A%'
        
        -- 下面的语句标示查询条件是第三个字符是A,且长度至少为4的stu_name
        WHERE stu_name LIKE '__A_%'
        
    • stu_name age score
      Sunny 18 98
      Robbin 18 96
      James 19 67
      Jane 17 82
      现在表中还是有如上数据
    • 执行下面操作
      -- 下面的语句用来查询表中stu_name的值为Ja开头,且至少长度为三的所有学生名字
      SELECT stu_name
      FROM Student
      WHERE stu_name LIKE 'Ja_%'
      
      得到如下结果
    • stu_name
      James
      Jane
    • 如果模式串(我们这里称like后面的串为模式串)中需要包含‘_’或者‘%’等通配符关键字,就需要用到转义,SQL里面用escape来指定转义字符
      • 举个栗子:
        -- 下面的语句在最后面定义‘\’为转义字符
        -- 所以实际的效果是匹配所有以 Ja_ 开头的 stu_name
        WHERE stu_name LIKE 'Ja\_%' escape '\'
        
  • 排序(order by)

    • 如果没有显示指定升序还是降序,则默认是采用升序的
    • null 值的处理(不同的数据库采取的处理不同)
      • Oracle 将null值当做最大
      • SQL Server 将null值当做最小
      • 接下来来去测测Mysql数据库
        • stu_name age score
          Sunny 18 98
          Robbin 18
          James 19 67
          Jane 17 82
          首先表中的数据是上面酱紫的
        • 然后执行下面操作
          -- 下面的语句查询学生表中的所有数据,并按成绩排序(因为没有指定
          -- 升序还是降序,所以默认是升序的)
          SELECT *
          FROM Student
          ORDER BY score;
          
          结果如下(可以看出,Mysql是将null值当做最小值)
        • stu_name age score
          Robbin 18
          James 19 67
          Jane 17 82
          Sunny 18 98
    • 在排序的时候可以用desc显示指定降序,asc显示指定升序
      • 举个栗子
        -- 下面的排序条件标示先按score降序排序,如果遇到score相同的,则按age升序排序
        ORDER BY score desc, age asc
        
      • order by 后面所跟字段,以在前面的字段为主进行排序
      • desc、asc 更在字段名或表达式后面,并且只能影响其前面的一个字段
        • 举个栗子
          -- 下面的排序条件表示,先以score进行升序排序(因为未指定的话默认是升序的),
          -- 如果遇到score相同的再按age进行降序排序
          order by score, age desc
          
    • order by 后面可跟别名,字段名,表达式,字段的顺序号
      • 别名、字段名
      • 表达式
        • 举个栗子
          -- 下面排序条件标示把sal*12后按结果降序排序
          order by 12 * sal desc
          
      • 字段的顺序号:
        • 举个栗子
          -- 下面这条语句标示查询Sudent表中的所有数据,并按age和score进行升序排序(默认是升序排序)
          SELECT student_name, age, score
          FROM Student
          ORDER BY 2, 3
          
    • 如果要查询的结果集是很大的,排序是很耗时的,会影响性能
  • where子句beween...and、in

    • between...and(表示一个连续的范围)
      • between a and b <==> a <= x <= b
      • not between a and b <==> x > b | x < a
      • 写的时候,小数写在前面,大数写在后面
    • in(表示离散的范围)
      • 举个栗子
        # 下面的语句表示查询分数为98、99或者100的学生的信息
        SELECT student_name, age, score
        FROM Student
        where score in (98, 99, 100)
        
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 50个常用的sql语句Student(S#,Sname,Sage,Ssex) 学生表Course(C#,Cname...
    哈哈海阅读 1,224评论 0 7
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • (一)Oracle数据库 1.oracle中row_id理解 ORACLE的row_id是一个伪列,其个是为18个...
    独云阅读 5,583评论 0 10
  • 可用产品战略与产品功能设计 阅读时间8分钟 今年的第一本书选择了《哲学的故事》,讲得是哲学大神们的故事。前面三分之...
    刘仙升阅读 554评论 2 2
  • 文|西贝玦 我再没有听见你的声音 从公交车上投下一枚响声清脆的硬币起 玻璃格子的车窗外装不下一整个世界 因为你没有...
    西贝玦阅读 141评论 0 1