美文网首页
sql笔记(一)简单数据操作

sql笔记(一)简单数据操作

作者: 艺术家可达鸭 | 来源:发表于2018-12-15 19:25 被阅读0次

    插入

    INSERT INTO tbl(col1,col2...) VALUES(val1,val2...),(val1,val2...),(val1,val2...);
    

    更新

    -- 这会把一整列的数据都更新,除非配合使用WHERE子句
    UPDATE tbl SET field=val, field=val;
    

    删除

    -- 这会删除表格中的所有数据,除非配合WHERE子句
    DELETE FROM tbl;
    

    查询

    SELECT col FROM tbl;
    

    DISTINCT

    去除查询结果中相同的行(每个字段都相同才可以)

    SELECT DISTINCT col FROM tbl;

    别名

    SELECT语句中可以给字段或者表格取别名,使用关键字AS,不过这个AS是可选的,在【原名】和【别名】之间直接用空格隔开,效果一样

    /*
    1. 字段的别名必须是一个字符串(但是定义的时候不加引号也是可以的),作用于查询结果,不能代码中,也就是说查询结果中id列的列名会显示为【序号】,而不是【id】,但是在该SELECT语句后面的子句中不能用【序号】来代替【id】
    2. 表格的别名是作用于代码的,后续子句中可以用【别名】代替【原名】,比如示例中用p代替people
    */
    SELECT id AS '序号' FROM people as p where p.id=1;
    

    LIMIT(MySQL & sqlite)

    限制SELECT查询输出的行数
    用LIMIT可以方便的输出表格的前几行,但是要输出倒数几行的话,目前我只知道需要表格有一个id列,然后根据id列倒序排列再用LIMIT子句

    -- 读取n行数据
    SELECT col FROM tbl LIMIT n;
    -- 从第m行开始,读取n行数据
    SELECT col FROM tbl LIMIT m,n;
    

    OFFSET

    设置SELECT语句从第几行开始查询
    sql表格的行数的下标也是从0开始的

    -- 这两行代码效果相同
    SELECT col FROM tbl LIMIT n,m;
    SELECT col FROM tbl LIMIT m OFFSET n;
    

    rownum(oracle)

    rownum是oracle中的一个伪列,表示行号,和mysql的offset不同,他是从1开始的。
    所以如果希望查询表格的前十行,只需要select * from tbl where rownum <= 10;即可。

    ORDER BY ... [DESC]

    SELECT * FROM tbl ORDER BY col [DESC];
    
    -- 根据多个条件排列结果,当前一个条件相等时,再使用后一个条件
    -- 如果都过条件都是升序,那可以不加[DESC/ASC],否则多个条件都加上[DESC/ASC]
    SELECT * FROM tbl ORDER BY col1 [DESC/ASC], col2 [DESC/ASC];
    

    oracle还支持nulls first/last关键字,自由选择null值排在最前面还是最后面。
    select * from tbl order by col desc nulls first;

    UNION 和 UNION ALL

    UNION和UNION ALL都是纵向连接多条SELECT语句的结果。
    举个例子,以下为表1,表2,以及用UNION连接的查询结果。

    SELECT col1 FROM tbl1 UNION SELECT col2 FROM tbl2;

    id id id
    1 2 1
    2

    所以UNION和UNION ALL对多条SELECT语句的查询结果有如下要求:

    1. 必须有相同数量的列
    2. 对应列(第一列对应第一列,第二列对应第二列)的列名和数据类型必须一样

    UNION和UNION ALL的区别是UNION会删除结果中相同的行,而UNION ALL不会。

    WHERE

    ... WHERE condition AND/OR condition;
    
    1. 和其他语言不同的是,数值大小判断中的【等于】是【=】,不是【==】
    2. 一般用来比较数值大小,对于字符串,一般只比较是否相等,WHERE field=val;

    LIKE

    用在WHERE子句中,用作字符串的匹配,可以使用如下通配符:
    %,表示任意字符。
    _,表示任意1个字符。
    [charlist],该字符序列中的任意一个字符。
    [^charlist],不在该字符序列中的任意一个字符。

    ... WHERE name LIKE '%TT%';
    

    REGEXP(MySQL)

    正则表达式,用法和LIKE一样。

    [NOT] BETWEEN AND

    mysql中BETWEEN...AND...包括上下边界。
    BETWEEN...AND...可以作用与数字,字符串,时间的话应该也没问题吧,二进制内容估计不行。

    SELECT * FROM tbl WHERE col BETWEEN val1 AND val2;
    

    [NOT] EXISTS

    SELECT * from tbl1 WHERE [NOT] EXISTS (SELECT * FROM tbl2 WHRER ...)

    EXISTS连接的多个SELECT类似于嵌套for循环,用java写的话,大概就像这样:

    List result=new ArrayList();
    for(int i:tbl1){
        for(int j:tbl2){
            if(i==j){
                result.add(i);
            }
        }
    }
    
    1. EXISTS并不关心子SELECT中返回的数据,只关心有没有数据返回,有则为真,否则为假
    2. EXISTS中的内外两条SELECT必须查询不同的表格,且子SELECT的WHERE语句中必须对两张表格中字段做比较判断,否则EXISTS将永远返回真,或者永远返回假,那EXISTS就没意义了
    3. 第二条SELECT中用到的tbl1中的字段不必存在于第一条SELECT中,只需要在tbl1中即可,比如SELECT col1 from tbl1 WHERE EXISTS (SELECT * FROM tbl2 WHRER tbl2.col1=tbl1.col2)

    对于上面说的第二点,举几个例子

    /*
    正确的做法
    第二条SELECT中只查询了tbl2,但是依旧使用了tbl1.col,这个tbl1.col就是前一条SELECT传进来的
    也就是说EXISTS中的SELECT相当于是内层for循环
    */
    SELECT * from tbl1 WHERE EXISTS (SELECT * FROM tbl2 WHERE tb1.col=tb2.col);
    
    /*
    错误的做法
    第二条SELECT中没有tbl1的数据,所以EXISITS中的SELECT永远返回真,或者永远返回假
    EXISTS无法起到筛选数据的作用
    */
    SELECT * from tbl1 WHERE EXISTS (SELECT * FROM tbl2 WHERE tbl2.col > var);
    
    /*
    错误的做法
    第二条SELECT没用到tbl2中的数据,能够筛选tbl1的数据,但是EXISTS语句在这里没有意义
    直接一个SELECT+WHERE就可以了
    */
    SELECT * from tbl1 WHERE EXISTS (SELECT * FROM tbl2 WHERE tbl1.col > var);
    

    是否需要用EXISTS

    从结果来看,EXISTS中的第二个SELECT中查询的表格只是用作对比,查询结果只会包含第一条SELECT查询的表格中的数据。
    但是不使用EXISTS也可以做到。

    SELECT tbl1.* FROM tbl1,tbl2 WHERE tbl1.col=tbl2.col;
    

    [NOT] IN

    IN的作用是给定一个元素集合,只要列中的元素存在于这个元素集合中,就返回真。
    这个元素集合可以直接给定,也可以使用SELECT子句的查询结果,但是,SELECT的查询结果必须是单列的。

    SELECT * FROM tbl1 WHERE tbl1.col IN (var1,var2,var3...);
    SELECT * FROM tbl1 WHERE tbl1.col IN (SELECT col FROM tb2);
    

    IN只能判断某一个字段是否在查询结果中,如果希望判断某几个字段,可以用括号。
    (col1,col2) IN (SELECT ...)

    IN与EXISTS效率比较

    子查询表大时,则用EXISTS;大小相似时都可以;子查询表小时,用IN。
    NOT EXISTS效率一定比NOT IN好。

    相关文章

      网友评论

          本文标题:sql笔记(一)简单数据操作

          本文链接:https://www.haomeiwen.com/subject/araahqtx.html