精华内容
下载资源
问答
  • 数据库基础语句

    万次阅读 多人点赞 2018-10-02 14:29:02
    文章目录DDL数据库表索引DML查找语句以及注意事项DCL别名group by的注意事项常见问题sql语句的执行顺序where和having的区别Not null unique和primary key的区别内连接 左连接 右连接 外连接MySQL中between and的取值...

    DDL

    DDL(数据库定义语言),用于数据库、表、列、索引等数据库对象的定义(创建)结构的修改

    数据库

    • 创建:create database 数据库名
    • 删除:drop database 数据库名
    • 改变使用的数据库:use 数据库名

    • 创建create table 表名(
      〈列名〉〈数据类型〉〈列级完整性约束条件〉……
      CONTRAINT〈约束名〉〈表级完整性约束条件〉……)
      • 列级约束条件
        • NOT NULL 或 NULL
          NOT NULL约束不允许字段值为空,而NULL约束允许字段值为空。
        • UNIQUE
          惟一性约束,即不允许列中出现重复的属性值。
        • PRIMARAY KEY [CLUSTERED|NON CLUSTERED]
          定义该字段为主码并建立聚集(非)索引。
          1、多个属性构成的主码只能通过表级约束条件定义:PRIMARY KEY (Sno,Cno)
          2、单个属性构成的主码可通过列级或表级约束条件定义:Sno CHAR(9) PRIMARY KEY 或 PRIMARY KEY (Sno)
        • DEFAULT
          默认值约束。 DEFAULT 默认值
          DEFAULT〈约束名〉〈默认值〉FOR〈列名〉
        • CHECK
          检查约束。CONSTRAINT〈约束名〉CHECK (〈约束条件表达式〉)
          1、单一属性设限
          CONSTRAINT C2 CHECK(性别 IN (‘男’,‘女’))
          CONSTRAINT C3 CHECK(成绩 BETWEEN 0 AND 100)
          2、多属性之间设限
          CHECK (Ssex=‘女’ OR Sname NOT LIKE ‘Ms.%’)
        • identity(初值,步长)
          定义字段为数值型数据,并指出它的初始值和逐步增加的步长值
        • reference 参照表(对应字段)
          定义该字段为外码,并指出被参照表及对应字段
        • AUTO_INCREMENT
          设置该字段为自增字段
        • 表级约束条件
        • UNIQUE(列1, 列2, …)
        • PRIMARY KEY[CLUSTERED|NON CLUSTERED](列1, 列2, …)
        • check(条件表达式)
        • FOREIGN KEY
          CONTRAINT〈约束名〉FOREIGN KEY(〈外码〉) REFERENCES〈被参照表名〉(〈与外码 对应的主码名〉)
      • 删除表drop table 表名
      • 修改表的约束or属性alter table 表名
        [rename 新表名] 更改表名
        [add column 列名 类型 约束 or CONSTRAINT 约束名 约束定义] 增加字段或者字段和表的约束
        [drop column 列名 or CONSTRAINT 约束名] 删除字段或约束
        [alter] 增加字段宽度或约束,一般不允许修改和减少,也不能改动字段标识
        [modify] 修改字段类型和约束,不能改动字段标识
        [change] 修改字段类型和约束,允许修改字段标识。后面要写两次列名,比较麻烦。
        {check|nocheck}constraint{all|约束名组}使约束有效或无效(check使之有效,nocheck使之无效,all指全部约束)
        first after:配合add、alter、modify、change使用,用于改变列的位置

    索引

    • 创建

      • create [UNIQUE] [CLUSTERED|NONCLUSTERED]
        index〈索引名〉 ON〈表名〉(〈列名〉[〈次序〉][,〈列名〉[〈次序〉]]…);

        UNIQUE
        建立唯一索引,不允许有两行具有相同索引值
        CLUSTERED|NONCLUSTERED
        建立聚集或者非聚集索引,每张表只能有一个聚集索引,默认值为非聚集索引

      • alter table 表名 add [UNIQUE|FULLTEXT] index 索引名 [using [BTREE|HASH]] (列名);
      • create table 表名{
        学号 char(6),
        课程号 char(3),
        成绩 tinyint(1),
        学分 tinyint(1),
        primary key(学号,课程号);
        index cj(成绩)//index 索引名 [索引类型] (索引列名)
        }
    • 删除drop index 索引名

    • 查看show index in 表名

    DML

    DML(数据库操纵语言),用于实现对数据库表的内容(而非结构)的增删改查功能。

    • 增加行
      INSERT INTO〈表名〉[(〈属性列1〉[,〈属性列2〉…)](不指定属性列时,需要把所有列都一一对应地写上)
      VALUES (〈常量1〉[,〈常量2〉]…),
         (〈常量1〉[,〈常量2〉]…)……

      INSERT INTO〈表名〉[(〈属性列1〉[,〈属性列2〉]…)]
      〈子查询〉

      • 如果想实现表中有重复的记录,则忽略本次插入的功能,可以通过INSERT IGNORE来实现这个功能:
        INSERT IGNORE INTO 〈表名〉
      • 如果想实现表中有重复的记录,则更新成本次插入的功能,可以通过INSERT ... ON DUPLICATE KEY UPDATE来实现这个功能:
        INSERT INTO first_table (first_column, second_column) VALUES(1, ‘哇哈哈’) ON DUPLICATE KEY UPDATE second_column = ‘雪碧’;
        这个语句的意思就是,对于要插入的数据(1, ‘哇哈哈’)来说,如果first_table表中有某些重复的记录,那就把记录的second_column列更新为’雪碧’
        INSERT INTO first_table (first_column, second_column) VALUES(1, ‘哇哈哈’) ON DUPLICATE KEY UPDATE second_column = VALUES(second_column);
        遇到重复记录时把该重复记录的second_column列更新成准备插入的记录中的值
    • 删除行
      DELETE FROM〈表名〉[WHERE〈条件〉];

    • 修改某几行的属性值
      UPDATE〈表名〉
      SET〈列名〉=〈表达式〉[,〈列名〉=〈表达式〉][,…n]
      [where]

    • 查找行

    查询-注意事项

    1. SELECT 〈属性1,属性2,……〉(可以使用distinct、top等关键字)
      from 表1,表2,……(可以有多个表,结果是笛卡尔乘积;可以是左右连接)
      where 元组需要满足的条件(可以用in)
    2. 可以对同一个列重复查询显示
      select num,num from strudentInfo;
      
    3. select后面的列是什么,临时表的列名就是什么
      select1,列2的表达式,……
      查询结果中,列名就是: 列1,列2的表达式,……
      

    查询-执行顺序

    SQL语言不同于其他编程语言的最明显特征是处理代码的顺序(书写查询语句也需要符合顺序)。在大多数据库语言中,代码按编码顺序被处理。但在SQL语句中,第一个被处理的子句式FROM,而不是第一出现的SELECT。SQL查询处理的步骤序号:

    (7)SELECT 投影,不删除结果中相同元组(注意,和关系运算中的投影π不同,π会删除结果中相同元素,相当于select distinct) (9) DISTINCT|TOP (11) <TOP_specification> <select_list>
    (12) INTO tablename 将结果保存到新表中
    (1) FROM <left_table> 笛卡尔乘积
    (3) <join_type> JOIN <right_table> 隐含的筛选条件
    (2) ON <join_condition> 筛选条件
    (4) WHERE <where_condition> 筛选条件
    (5) GROUP BY <group_by_list> 分组
    (6) WITH {CUBE | ROLLUP}
    (8) HAVING <having_condition> 筛选条件
    (10) ORDER BY <order_by_list> ASC|DESC 排序条件

    查询-分类

    • 简单查询
      查询过程中只涉及到一个表的查询
    • 连接查寻
      • where子句中,使用=的连接查询
        • 自身连接:MySQL服务器会把名称一样的表当作是一个表处理,名称不同的当做不同的表处理。
          下面的语句中,t1和t2会都被当做不同的表(相当于赋值了一个和test一样的表,和test进行连接查询),查询结果是两个test笛卡尔乘积后,留下满足条件的结果。
          select * from test as t1, test as t2 where t1.num=t2.num;
          下面的语句中,是一个表,查询结果为test原表
          select * from test as t1, test as t2 where t1.num=t2.num;
          
        • 复合连接:多个表的=连接
      • from子句中,使用join的连接查询
        • 内连接:使用innner join 或 cross join 或 join,等效于 from t1,t2。
          后可跟连接条件:where 连接条件, on 连接条件, using 相同列名
        • 外连接:使用了full join、left join、right join的全、左、右外连接查询
          后只能跟连接条件: on 连接条件(on后面可再加where,但是不能直接用where)
        • 交叉连接:使用了cross join的交叉连接查询。返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积。
    • 嵌套查询
      引出了子查询概念。一个select from where成为一个查询块。
      • 按照使用的运算符分类:
        • 使用比较运算符(如> < =)连接子查询select
        • 使用范围运算符(如in,any,all,exists)连接子查询select
      • 按照子查询和父查询的依赖关系分类:
        • 相关子查询:子查询的查询条件依赖于父查询。依次取父查询中每一个元组,处理内查询,为真则保留结果。

          执行过程:
          (1)从外层查询中取出一个元组,将元组相关列的值传给内层查询。
          (2)执行内层查询,得到子查询操作的值。
          (3)外查询根据子查询返回的结果或结果集得到满足条件的行。
          (4)然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。

        • 非相关子查询:子查询条件不依赖与父查询。即子查询可以完全脱离父查询单独执行
    • 集合查询
      使用了union(并)、intersect(交)、minus(差)关键字的查询。
      注意:
      • 查询的结果集中显示的列名将以第一个查询中的列名为准
      • 被合并的各个查询的查询对象个数必须相同类型不必完全相同
      • 单独使用,系统会自动去掉重复的元组。union all则会保留重复的元素。
      • 有的数据库没有intersect和minus,需要通过exists实现差和交操作。
    • 分组查询
      使用了group by的查询

    SELECT TOP 子句

    SELECT TOP 子句用于规定要返回的记录的数目。并非所有的数据库系统都支持 SELECT TOP 语句。

    数据库 选取前几列的实现方式
    SQL Server / MS Access SELECT TOP 语句
    MySQL LIMIT 开始行(从0开始),限制条数
    Oracle ROWNUM 语句

    例子:从"Customers"表中选择前三个记录:

    # SQL Server / MS Access
    SELECT TOP 3 * FROM Customers;
    # MySQL
    SELECT * FROM Customers
    LIMIT 3;
    #  Oracle
    SELECT * FROM Customers
    WHERE ROWNUM <= 3;
    

    例子:从"Customers"表中选择记录的前50%:

    SELECT TOP 50 PERCENT * FROM Customers;
    

    查询-运算符

    假设变量 a 的值为 10, 变量 b 的值为 20

    • 算数运算符
    操作符 描述 示例
    + 相加:将符号两边的数值加起来。 a + b 得 30
    - 相减:从最边的操作数中减去右边的操作数。 a - b 得 -10
    * 相乘:将两边的操作数相乘。 a * b 得 200
    / 相除:用右边的操作数除以左边的操作数。 b / a 得 2
    DIV 相除:取商的整数部分。 b / a 得 2
    % 取余:用右边的操作数除以左边的操作数,并返回余数。 b % a 得 0
    • 比较运算符
    操作符 描述 示例
    = 检查两个操作数的值是否相等,是的话返回 true。 (a = b) 不为 true。
    != 检查两个操作数的值是否相等,如果不等则返回 true。 (a != b) 为 true。
    <> 检查两个操作数的值是否相等,如果不等则返回 true。 (a<>b) 为真。
    > 检查左边的操作数是否大于右边的操作数,是的话返回真。 (a > b) 不为 true。
    < 检查左边的操作数是否小于右边的操作数,是的话返回真。 (a < b) 为 true.
    >= 检查左边的操作数是否大于或等于右边的操作数,是的话返回真。 (a >= b) 不为 true。
    <= 检查左边的操作数是否小于或等于右边的操作数,是的话返回真。 (a <= b) 为 true.
    !< 检查左边的操作数是否不小于右边的操作数,是的话返回真。 (a !< b) 为 false.
    !> 检查左边的操作数是否不大于右边的操作数,是的话返回真。 (a !> b) 为 true。
    • 逻辑运算符
    操作符 描述
    AND AND运算允许多个条件在SQL语句中,存在WHERE子句
    OR OR运算符是用来多个条件WHERE子句结合起来的SQL语句
    NOT NOT是一个否定运算符。例如:NOT EXISTS,NOT BETWEEN,NOT IN,NOT LIKE等
    • 范围运算符
    操作符 描述
    BETWEEN BETWEEN运算符用于搜索是在一组值的那个值,给定的最小值和最大值
    EXISTS 代表存在,exists操作符后子查询结果集如果不为空(即只要存在一条满足),则返回true,否则返回false
    IN IN运算符用于一个值进行比较,以已被指定的文字值的列表
    ALL ALL运算符是用来在另一个值设定比较值的所有值,可以和比较运算符一起使用
    ANY ANY运算符用于根据条件在列表中的值进行比较的任何应用值,可以和比较运算符一起使用
    SOME 一些,可以和比较运算符一起使用
    • 字符串运算符
    操作符 描述
    + 连接
    LIKE LIKE运算符用来比较使用通配符运算符相似的值
    • 其他运算符
    操作符 描述
    IS NULL NULL运算符用来比较一个NULL值
    UNIQUE UNIQUE操作搜索指定表的每一行的唯一性(不重复)

    查询-通配符

    如果需要匹配 % 和 _ ,则需要使用 \ 进行转义。

    通配符 描述
    % 替代 0 个或多个字符
    _ 替代一个字符
    [charlist] 字符列中的任何单一字符
    [^charlist] 或 [!charlist] 不在字符列中的任何单一字符

    查询-聚集函数

    SQL函数

    函数 描述
    SUM(column) 返回某列的总和
    AVG(column) 返回某列的平均值
    FIRST(column) 返回在指定的域中第一个记录的值
    LAST(column) 返回在指定的域中最后一个记录的值
    MAX(column) 返回某列的最高值
    MIN(column) 返回某列的最低值
    COUNT(*) 返回被选行数
    COUNT(column) 返回某列的行数(不包括 NULL 值)
    COUNT(DISTINCT column) 返回相异结果的数目

    查询-表达式

    表达式主要有以下两种使用:

    1. 作为查询对象
      select num+50 from t1; --列名就是 num+50 ,列值是t1的 num+50
      
    2. 作为查询条件
      select num from t1 where num>50; 
      

    group by的注意事项

    • 在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚集函数(可以不是group by子句中指定列的聚集函数),原因在于最终的结果集中只为每个组包含一行。并且此时,检索列表中的表达式和GROUP BY子句中的表达式必须完全一样,而且不能使用别名
    • 由于最终的结果集中只为每个组包含一行,对于不包含聚集函数的group by语句,筛选结果只保留第一个结果值,相当于使用了distinct
      --结果是显示每个部门的名称(无重复)
      select 部门 from table 
      group by 部门 
      
    • 如果分组列中含有NULL值,那么NULL也会作为一个独立的分组存在。
    • GROUP BY子句后也可以跟随表达式,但不能是聚集函数(很显然,根据聚集函数无法分组)
    • group by和group by all的区别
      • group by all 不管where的筛选条件,而对表中所有的行根据属性进行分组并显示在结果集中
      • 如果select里面有聚集函数,则group by all 中不符合where筛选的结果显示为null
      select 类别,AVG(定价) 平均价 from 图书馆
      where 出版社='机械出版社'
      group by 类别
      
      --会对出版社非机械出版社的书也根据类别进行分组,只不过对应的平均价为null
      select 类别,AVG(定价) 平均价 from 图书馆
      where 出版社='机械出版社'
      group by all 类别
      

    DISTINCT-去重

    • 使用格式
      SELECT DISTINCT 列名1, 列名2, ... 列名n  FROM 表名;
      
    • 注意事项
      distinct会将结果中重复的行去除,即没有任何两行“列名1, 列名2, … 列名n”完全相同

    null值检查

    null代表没有值,判断某一属性是否为null时,不能用 = ,不能用通配符(任意字符不等于没有字符),必须用is (not)

    DCL

    DCL(数据库控制语言),用于控制访问权限和设定安全级别。

    • grant
      • 功能:授权
      • 格式
        grant 权限列表 on.to 用户名@'ip' identified by "密码" [WITH GRANT OPTION];
        
      • 应用
        • 普通数据用户,查询、插入、更新、删除 数据库中所有表数据的权利。
          grant select on testdb.* to common_user@ '%'
          grant insert on testdb.* to common_user@ '%'
          grant update on testdb.* to common_user@ '%'
          grant delete on testdb.* to common_user@ '%'
          --上面四条可以合成下面1条
          grant select, insert, update, delete on testdb.* to common_user@ '%'
          --all等同于all privileges,其中的privileges可以省略
          grant all on *.* to wang@ '192.168.1.150' identified by "password"; 
          --把查询权限授予所有用户
          GRANT SELECT ON TABLE SC TO PUBLIC;
          --把INSERT权限授予用户U5,并允许将此权限再授予其他用户
          GRANT INSERT ON TABLE SC TO U5 WITH GRANT OPTION;
          --192.168.1.%表示一个网段
          grant all privileges on *.* to wang@'192.168.1.%' identified by "123456";    
          --grant 作用在表中的列上:
          grant select(id, se, rank) on testdb.apache_log to dba@localhost;
          --授权之后,不要忘记更新权限表
          flush privileges      
          
        • 数据库开发人员,创建表、索引、视图、存储过程、函数等权限。
          --grant 创建、修改、删除 MySQL 数据表结构权限。
          grant create on testdb.* to developer@ '192.168.0.%'; 
          grant alter on testdb.* to developer@ '192.168.0.%'; 
          grant drop on testdb.* to developer@ '192.168.0.%';
          --grant 操作 MySQL 外键权限:
          grant references on testdb.* to developer@ '192.168.0.%';
          --grant 操作 MySQL 临时表权限:
          grant create temporary tables on testdb.* to developer@ '192.168.0.%';
          --grant 操作 MySQL 索引权限:
          grant index on testdb.* to developer@ '192.168.0.%';
          --grant 操作 MySQL 视图权限
          grant create view on testdb.* to developer@ '192.168.0.%'; 
          --grant 操作 MySQL 存储过程、函数权限:
          grant create routine on testdb.* to developer@ '192.168.0.%'; -- now, can show procedure status 
          grant alter routine on testdb.* to developer@ '192.168.0.%'; -- now, you can drop a procedure 
          grant execute on testdb.* to developer@ '192.168.0.%';
          grant execute on procedure testdb.pr_add to 'dba'@ 'localhost';
          grant execute on function testdb.fn_add to 'dba'@ 'localhost';
          
        • 查看权限
          --查看当前用户下所有的权限
          show grants;
          --查看其他 MySQL 用户权限:
          show grants for dba@localhost;
          
          
    • revoke
      • 功能: 收回权限
      • 格式: revoke跟grant语法差不多,只需要把关键字 “to” 换成 “from” 即可,并且revoke语句中不需要跟密码设置。
        revoke 权限列表 on.from 用户名@'ip';
        
      • 应用
        --撤销已经赋予给 MySQL 用户权限的权限。
        revoke all on *.* from dba@localhost;
        revoke insert,select,update,delete,dropcreatealter on huanqiu.* from wang@'%';
        flush privileges;
        

    grant和revoke的注意事项

    • grant, revoke用户权限后,该用户只有重新连接MySQL数据库,权限才能生效。
    • 如果想让授权的用户,也可以将其拥有的权限grant给其他用户,那么授权时需添加选项 “grant option”!
    • mysql授权表一共涉及到5个表,分别是user、db、host、tables_priv和columns_priv。
      这5张表的内容和用途如下:

      1)user表
      user表列出可以连接服务器的用户及其口令,并且它指定他们有哪种全局(超级用户)权限。在user表启用的任何权限均是全局权限,并适用于所有数据库。例如,如果你启用了DELETE权限,在这里列出的用户可以从任何表中删除记录,所以在你这样做之前要认真考虑。
      2)db表
      db表列出数据库,而用户有权限访问它们。在这里指定的权限适用于一个数据库中的所有表。
      3)host表
      host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限,这可能比单独使用db好些。这个表不受GRANT和REVOKE语句的影响,所以,你可能发觉你根本不是用它。
      4)tables_priv表
      tables_priv表指定表级权限,在这里指定的一个权限适用于一个表的所有列。
      5)columns_priv表
      columns_priv表指定列级权限。这里指定的权限适用于一个表的特定列。

    • 如果给一个用户设置的权限过大,除了上面使用revoke回收部分权限外,还可以使用grant进行权限修改。也就是说,grant不仅可以添加权限,也可以修改权限(实际上就是对同一’用户名’@'ip’设置权限,以覆盖之前的权限);grant修改后的权限将覆盖之前的权限!

    别名

    用别名(Alias)来对数据表或者列进行临时命名。重命名是临时的,数据库中表的实际名字并不会改变。
    为表或者列设置别名的方法有两种:

    • 表名or临时表or属性名 as 别名
    • 表名or临时表or属性名+空格+别名

    注意:

    1. 别名只会在本次查询结果中显示,而不会改变表中真实的列名;
      mysql> SELECT number AS 学号 FROM student_info;
      +----------+
      | 学号     |
      +----------+
      | 20180104 |
      | 20180102 |
      | 20180101 |
      +----------+
      6 rows in set (0.00 sec)
      
    2. 在查询语句中,使用别名后,后面的查询就必须用别名,而不能用原来的名字了。

    数据类型

    SQL数据类型

    类型转换

    当某个值的类型与上下文要求的类型不符时,MySQL就会根据上下文环境中需要的类型自动对该值进行类型转换。

    • 类型转换的场景:
    1. 把操作数类型转换为适合操作符计算的相应类型
      1 + 23
      '1' + 23
      '1' + '2'3
      
    2. 将函数参数转换为适合函数的类型
      以拼接字符串的CONCAT函数举例:
      CONCAT('1', '2')'12'
      CONCAT('1', 2)'12'
      CONCAT(1, 2)'12'
      
    3. 存储(insert)数据时,把某个值转换为某个列需要的类型
      CREATE TABLE t (
          i1 TINYINT,
          i2 TINYINT,
          s VARCHAR(100)
      );
      INSERT INTO t(i1, i2, s) VALUES('100', '100', 200);
      
      我们为列i1和i2填入的值是一个字符串值:‘100’,列s填入的值是一个整数值:200,虽然说类型都不对,但是由于自动转型的存在,在插入数据的时候字符串’100’会被转型为整数100,整数200会被转型成字符串’200’,所以最后插入成功。
    • 类型转换的方式:MySQL会尽量把值转换需要的类型。
    1. 类型转换:字符和数字的转换,‘23’ → 23
    2. 类型提升:200存入TINYINT型中,TINYINT变为BIGINT型
    3. 截取部分:如在进行加法计算时,‘23sfd’ → 23

    常见问题

    select 1 和 select null

    • select 1
      select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,一般是作条件查询用。
      从效率上来说,1>xxx>*,因为不用查字典表。
      1Select n(数字) from table
      得出一个行数和table表行数一样的临时列,每行的列值是我写在select后的数(n)2Select count(n) from table
      得出一个数,该数是table表的行数;
      3Select sum(n) from table
      得出一个数,该数是table表的行数×写在select后的数(n)
    • select null
      与 select 1 相似。只不过返回的列值为 null,且不可以使用count 和 sum 函数

    = 、in 、exists 的区别

    • =
      用于限定某一属性的唯一取值。= 右面的取值不能是一个范围。可以使用 = any 等实现范围限定。
    • in
      当右面接子查询的时候,先运行子查询,在运行上级查询。
    • exists
      当右面接子查询的时候,从上一级查询中依次取出每条元组,判断是否满足子查询。
    代码示例:查询所有未修1号课程的学生姓名
    1、错误示例:(错误原因:一个学生可能选多种课程)
    	SELECT Sname
    	FROM Student,SC
    	WHERE Student.Sno=SC.Sno AND Cno <>'1'
    2、正确写法:
    a.exists
    	SELECT Sname
    	FROM Student
    	WHERE NOT EXISTS
    	(SELECT *
    	FROM SC
    	WHERE Sno = Student.Sno AND Cno=1);
    b.in
    	SELECT Sname
    	FROM Student
    	WHERE sno NOT IN
    	(SELECT Sno
    	FROM SC
    	WHERE Cno==1)
    

    where和having的区别

    where having
    from后表中的所有字段进行筛选,而不能对group by分组后的数据筛选(也就是说只能对返回的查询结果集进行过滤操作 select from的结果或者group by分组后的结果进行筛选
    不能使用聚集函数 可以使用聚集函数
    • where和having都可以使用的场景:
      select goods_price,goods_name from sw_goods where goods_price > 100
      
      select goods_price,goods_name from sw_goods having goods_price > 100
      
      解释:上面的having可以用的前提是我已经筛选出了goods_price字段,在这种情况下和where的效果是等效的,但是如果我没有select goods_price 就会报错!!因为having是从前筛选的字段再筛选,而where是从数据表中的字段直接进行的筛选的。
    • 只可以用where,不可以用having的情况:
      select goods_name,goods_number from sw_goods where goods_price > 100
      
      -- 报错!!!因为前面并没有筛选出goods_price 字段
      select goods_name,goods_number from sw_goods having goods_price > 100 
      
    • 只可以用having,不可以用where情况:
      select goods_category_id , avg(goods_price) as ag from sw_goods group by goods_category having ag > 1000
      
      -- 报错!!因为from sw_goods 这张数据表里面没有ag这个字段
      select goods_category_id , avg(goods_price) as ag from sw_goods where ag>1000 group by goods_category
      
      注意: where 后面要跟的是数据表里的字段,如果我把ag换成avg(goods_price)也是错误的!因为表里没有该字段。而having只是根据前面查询出来的是什么就可以后面接什么。

    Not null unique和primary key的区别

    DBMS会给primary key建立索引

    drop turncate delete的区别

    • drop
      将表占用的空间全部释放,包括数据和表的定义结构
    • truncate
      一次性地从表中删除所有数据,通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。
      最直观的是 truncate 之后自增字段是从头开始计数,而delete仍保留着原来的最大数值。
      TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。 对于外键(foreignkey )约束引用的表,不能使用 truncate table,而应使用不带 where 子句的 delete 语句
    • delete
      每次从表中删除一行,并且把同时把该行的删除操作作为事务记录在日志中保存,以便进行回滚

    内连接 左连接 右连接 外连接

    假设左表有M行,右表有N行,x=max(M,N),y=min(M.N)

    • 内连接:笛卡尔乘积结果中,满足删选条件的部分,最少0行,最多M×N行(全匹配,即笛卡尔乘积
    • 左连接:内连接(匹配结果)+左表中没有匹配的元组,最少M行,最多M×N行(全匹配)
    • 右连接:内连接(匹配结果)+右表中没有匹配的元组,最少N行,最多M×N行(全匹配)
    • 外连接:内连接(匹配结果)+两表中没有匹配的元组,最少x行,最多M×N行

    MySQL中between and的取值范围

    1、取 1<=x<=100的值,即包含两边的边界值
       between 1 and 100 
    2not  between的范围是不包含边界值
    3、当使用带有日期值的BETWEEN运算符时,为了获得最佳结果,应使用类型强制转换将列或表达式的类型显式转换为DATE类型。
       例如,要获取所需日期为01/01/200301/31/2003的订单,请使用以下查询:
        SELECT orderNumber,
              requiredDate,
              status
    	FROM orders
    	WHERE requireddate
    	    BETWEEN CAST('2003-01-01' AS DATE)
    	        AND CAST('2003-01-31' AS DATE);
      如果是datetime类型,‘2003-01-31’ 会被转成’2003-01-31 00:00:00’类型,就查不出来2003-01-31的数据
    

    char varchar nchar nvarchar

    容量 长度 编码
    char 8000个英文,4000个汉字 定长 非Unicode
    varchar 8000个英文,4000个汉字 变长 非Unicode
    nchar 4000个字符,无论英文还是汉字 定长 Unicode编码
    nvarchar 4000个字符,无论英文还是汉字 变长 Unicode编码
    • Unicode或非Unicode
      • 占用字节不同
        非Unicode:英文占用1个字节,汉子等需要占用两个字节
        Unicode:所有的字符都用两个字节表示,即英文字符也是用两个字节表示。
      • 适用场景不同
        如果英文与汉字同时存在,占用空间数不同,容易造成混乱,导致读取出来的字符串是乱码
        非Unicode:适合存储纯英文和数字,以节省空间
        Unicode:适合含有中文字符的情况,以防止乱码
    • 定长和变长
      • 占用长度不同:
        定长中,char(10)表示字符长度为10,不满10个补充空格
        变长中,vchar(10)表示最多存储10个字符,实际长度为存储的字符串长度+1(多出的字节用于保存实际使用了多大长度)
      • 存储效率不同:
        定长数据存储效率更高

    通配符和占位符的区别

    • 通配符:在字符串匹配中替代一个或多个字符( 详情
    • 占位符:在SQL语句中代替具体值,执行SQL语句时再接收参数
      • ?:原生JDBC中就有,用来在PreparedStatement中代替传入参数的位置( 详情
      • #{}${}:MyBatis占位符 ( 详情

    参考文献

    https://www.jianshu.com/p/bb19b6b0fdc3 sql语句执行顺序
    http://keep.iteye.com/blog/240665 group by和having/where的区别
    https://segmentfault.com/a/1190000008284099 having/where的区别
    https://www.jb51.net/article/91915.htm grant revoke语句
    https://www.cnblogs.com/kevingrace/p/5719536.html grant revoke语句
    https://blog.csdn.net/liuwengai/article/details/51321198 grant revoke语句
    https://troywu0.gitbooks.io/spark/content/shu_ju_ku_suo_yin.html 索引操作语句
    https://www.yiibai.com/sql/sql-operators.html sql运算符
    https://www.w3cschool.cn/sql/dlwiyfom.html SELECT TOP, LIMIT, ROWNUM
    https://www.cnblogs.com/jiechn/p/3979261.html select 1
    https://blog.csdn.net/lwl20140904/article/details/73882306 select null与select 1区别
    https://blog.csdn.net/jueblog/article/details/9673505 in和exist的区别
    https://blog.csdn.net/lick4050312/article/details/4476333 in和exist的区别
    https://blog.csdn.net/jiuqiyuliang/article/details/10474221 交叉连接
    https://github.com/whlmpower/JavaNote/blob/master/MySQL/SQL%E5%8F%82%E7%85%A7%E6%95%B0%E6%8D%AE%E8%AF%BE%E7%A8%8B%E8%AE%B2%E4%B9%89%E6%A2%B3%E7%90%86.md drop truncate delete 区别
    http://www.manongjc.com/mysql_basic/mysql-between-and-basic.html between and 的边界问题
    https://blog.csdn.net/qq_17011423/article/details/69220231 between and 时间边界问题
    http://www.cnblogs.com/smjack/archive/2008/04/14/1152342.html char、varchar、nchar、nvarchar的区别
    https://www.cnblogs.com/lichang1987/archive/2009/03/04/1403166.html char、varchar、nchar、nvarchar的区别
    https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483845&idx=1&sn=e52cf475a4b0c24989fd0bce37af2efa&scene=19#wechat_redirect 类型转换

    展开全文
  • 数据库sql判断语句(case,IF)

    千次阅读 2016-06-02 14:11:25
    上面的数据库语句标红部分,是使用了sql判断语句(case),下面介绍case的使用: 已这个数据库语句为例子: (case when a.cat_id<>'null' then count(*) else '0' end) 当a.cat_id不等于null时,则输出count...


    "select b.cat_id,(case when a.cat_id<>'null' then count(*) else '0'  end)as goods_num from ".$GLOBALS['ecs']->table('goods'). " as a right join ".$GLOBALS['ecs']->table('category'). " as b on a.cat_id=b.cat_id group by b.cat_id";

    上面的数据库语句标红部分,是使用了sql判断语句(case),下面介绍case的使用:

    已这个数据库语句为例子:

    (case when a.cat_id<>'null' then count(*) else '0'  end)

    当a.cat_id不等于null时,则输出count(*),否则输出0.


    case when的详细用法,请参照以下链接:

    http://lj.soft.blog.163.com/blog/static/7940248120109215191358/




    IF的使用

    select * ,if(a>b,a,b) as pid from table;

    注意a和b都是数据表的字段

    IF的第一个参数为条件,条件成立输出a,否则输出b

    展开全文
  • 数据库简单语句-去重

    千次阅读 2017-03-23 14:19:12
    简单数据库语句记了又记 :0、 select peopleId,count() from people group by peopleId having count() >1;“`1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people ...
    select peopleId,count(*) from people group by peopleId having count(*) >1
    

    1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断

    select * from people where peopleId in (select   peopleId from   people group by   peopleId having count(peopleId) > 1)  
    

    *2、*删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录

    delete from people   
    where peopleId in (select   peopleId from people group by   peopleId   having count(peopleId) > 1)  
    and rowid not in (select min(rowid) from   people group by peopleId having count(peopleId  )>1) 
    

    *3、*查找表中多余的重复记录(多个字段)

    select * from vitae a  
    where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) 
    

    *4、*删除表中多余的重复记录(多个字段),只留有rowid最小的记录

    delete from vitae a  
    where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having  count(*) > 1)  
    and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)  
    

    *5、*查找表中多余的重复记录(多个字段),不包含rowid最小的记录

    select * from vitae a  
    where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having  count(*) > 1)  
    and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)  
    
    展开全文
  • JAVA 数据库SQL语句批处理

    千次阅读 2017-08-10 23:01:50
    对于数据库的批处理,首先需要做的是查询数据库是否支持批处理

    对于数据库的批处理,首先需要做的是查询数据库是否支持批处理
    下面是实现的代码

    /**
         * 判断数据库是否支持批处理
         * @param con
         * @return
         */
        public static boolean supportBatch(Connection con){
            try {
                // 得到数据库的元数据
                DatabaseMetaData md = con.getMetaData();
                return md.supportsBatchUpdates();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return false;
        }
        /**
         * 执行一批SQL语句
         * @param con   数据库的连接
         * @param sqls  待执行的SQL数组
         * @return
         */
        public static int[] goBatch(Connection con, String[] sqls){
            if (sqls == null){
                return null;
            }
            Statement sm = null;
            try {
                sm = con.createStatement();
                // 将所有的SQL语句添加到Statement中
                for (int i=0; i<sqls.length; i++){
                    sm.addBatch(sqls[i]);
                }
                // 一次执行多条SQL语句
                return sm.executeBatch();
    
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                OperateDB.closeStatement(sm);
            }
            return null;
        }

    关于sql语句的批处理,上面只是一个简单的代码,具体开发的时候,对于sql语句的多条处理,最好的方式是使用事务进行处理,这样可以让sql语句的执行一致。并且在出现异常的时候可以进行事务回滚。还有值得一提的是,关于Statement和prepareStatement对sql语句进行操作的时候,最好是使用prepareStatement。具体的原因在于
    1、PrepareStatement 提高性能
    2、提高代码的可读性和可维护性
    3、安全性 PrepareStatement防止了SQL注入,提高了程序的安全性。
    所以在进行sql操作的时候尽量使用prepareStatement

    展开全文
  • 数据库选择语句的使用

    千次阅读 2018-04-17 12:05:22
    case when对成绩判断非常方便 select  username, case   when  yuwen>=80  then   '优秀'     when  (yuwen and yuwen>=60)  then   '及格'     when  (yuwen)  then   '差'   end   as...
  • MySql数据库基本语句

    千次阅读 2019-04-09 23:07:21
    一,DML语句之Delete(删除) 格式:delete from 表单名; 其后可以增加where条件限制,order by排序,limit限制 例如:delete from employee where name=‘ls’; 删除表中名字为李四的记录。 还有一个删除是...
  • MySQL数据库count语句详解

    千次阅读 2019-11-25 15:35:43
    select count(*) 应该是一个比较常用的语句,用来统计记录行数。 但是,慢慢地你会发现,这个语句越来越慢了,为什么呢? count(*) 的实现方式 首先,我们来看下它的实现方式。 MySQL 中,不同的存储引擎,count...
  • SQL:数据库更新语句操作实例

    千次阅读 2020-12-13 14:56:09
    SQL Server数据库更新操作 名称解释(不区分大小写) student:学生表,属性分别为sno学号、sname学生姓名、age年龄、sex性别、dno学院编号、birthday生日 sc选课信息表:sno学号、cno课程号、grade成绩 dept学院...
  • 根据字段dsdate选择月份,以下语句可以判断一个月份的季度, SQL语句为: CASE WHEN SUBSTR(dsdate,6,2) BETWEEN 1 AND 3 THEN 1 WHEN SUBSTR(dsdate,6,2) BETWEEN 4 AND 6 THEN 2 WHEN SUBSTR(dsdate,6,2...
  • 经典的数据库查询语句大全

    千次阅读 2015-04-14 14:24:05
    (转)经典SQL查询语句大全 (2011-05-25 21:49:10)转载▼ 标签: 杂谈 一、基础 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份sql server ...
  • 数据库sql语句的exists总结

    千次阅读 2015-05-08 14:50:10
    数据库sql语句的exists总结 sql exists in 学习   先来比较下语法: --deals=交易表,areas=地域表,例如香港;我们的目的:查看有交易的地域 select * from areas where id in (select city_id ...
  • 数据库操作语句大全(sql)

    万次阅读 多人点赞 2019-03-23 14:54:20
    1.1、说明:创建数据库 CREATE DATABASE database-name 1.2、说明:删除数据库 drop database dbname 1.3、说明:备份sql server 创建 备份数据的 device USE master EXEC sp_addumpdevice 'disk', 'testBack',...
  • [color=green]★★★ 本篇为原创...在一般情况下,SQL的条件判断语句都是用在select后面,例如mysql的if条件判断,或者oracle的decode条件判断,当然其他的数据库大家可以自己测试下,几乎很少会把条件判断用在wher...
  • 数据库查询语句内连接外连接效率

    千次阅读 2018-12-06 22:20:45
    今天老大问到内连接外连接的查询速度问题,之前没有了解过因为做的项目比较小所以没有在效率上考虑过。今天问到了就查一下文档和大佬们的博客总结...但是具体效率并没有多少区分还是由语句决定大部分的执行效率。...
  • mysql查看数据库索引语句

    万次阅读 2018-02-08 09:09:50
    -- developerclub为数据库名称,到时候只需要修改成你要导出表结构的数据库即可  table_schema ='developerclub'  AND  -- article为表名,到时候换成你要导出的表的名称  -- 如果不写的话,默认会查询出所有表...
  • MySQL 数据库 IF 语句的使用详解

    千次阅读 2019-04-28 23:38:38
    MySQL的 if 既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用: IF表达式: IF(expr1, expr2, expr3) 说明: 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),...
  • Mysql数据库If语句的使用

    万次阅读 2016-11-18 16:47:02
    MySQL的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用: IF表达式 [sql] view plain copy   IF(expr1,expr2,expr3)  如果 expr1 是TRUE...
  • 通用SQL数据库查询语句大全

    千次阅读 2013-08-20 13:48:15
    一、 简单查询  简单的Transact-SQL查询只包括选择列表、FROM子句和... 例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。  SELECT nickname,email  FROM testtable  WHERE name
  • Mysql数据库if语句case when使用

    千次阅读 2016-07-03 15:28:37
    Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用: IF表达式 IF(expr1,expr2,expr3)如果 expr1 是TRUE (expr1 NULL),则 IF()的返回值为expr2; 否则返回值则为 ...
  • 那么在数据库优化中,sql 语句的优化就很重要了。 sql 语句怎么写,可能会有不同的执行效率和所需要的资源。下面是一种oracle 自带的一种,可以判断你所使用的资源。通过对比你可以判断使用哪种sql 对你的帮助更大 ...
  • 前两天又装了oracle,开始再次学习数据库,希望这次可以系统的学习,主要是语句的学习。 数据库操作语句SQL 一、select 查询语句 二、DDL 数据 定义 语句(create、drop、alter) 三、DML 数据 操作 语句(insert...
  • 查询数据库空表有哪些: use 库名 go declare @tablename nvarchar(100) declare @sql nvarchar(2000) declare @count int declare @a int declare cur_c cursor for select name from sysobjects w...
  • // 在SqLite中创建表的语句 //创建表SQL语句    String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)"; //执行SQL语句     db...
  • 通用SQL数据库查询语句精华使用简介http://tech.163.com/school · 2005-04-05 11:01:31 · 来源: 网易社区 一、 简单查询 简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、...
  • 数据库_MySQL: mysql判断和循环语句

    千次阅读 2019-03-16 21:29:47
    1.if判断语句 语法: if 条件 then #SQL语句 elseif 条件 then #SQL语句 elseif 条件 then #SQL语句 .... else #SQL语句 end if; 创建存储过程(p1)传递一个整数参数判断大于90分优秀,反之不优秀 drop ...
  • 1、可以在创建表之前判断,这样就不会重新创建,create table if not exists Student(stu text primary key, name text); 比平时的创建表多了if not exists 2、String sql = "select name from sqlite_master ...
  • 数据库SQL语句的增删改查(总结)

    万次阅读 2017-02-14 14:49:14
    一、增:有2种方法 1.使用insert插入单行数据:  语法:insert [into] [列名] values  例:insert into Strdents (姓名,性别,出生日期) values ('王伟华','...2.使用insert,select语句将现有表中的 数据添加到已
  • 判断数据库死锁的Sql语句

    千次阅读 2006-08-10 15:09:00
    判断数据库死锁的Sql语句 sp_lock select convert (smallint, req_spid) As spid, rsc_dbid As dbid,db.name as DBName, rsc_objid As ObjId,object_name(rsc_objid) as ObjectName, rsc_indid As IndId, ...
  • IF EXISTS(select * from sysdatabases where name="E_market") DROP DATABASE E_market 语句如上 报错,显示 列名“E_market”无效 求大神指导,谢谢!
  • 数据库的检索语句

    千次阅读 2014-10-23 15:22:28
    1、SELECT 基本用法  1.1简单的数据检索 1.1.1检索出需要的列 ...SELECT * FROM T_Employee语句会把数据库的所有列的信息从数据库中读出来,缓存到内存中。检索出所有的列的 SQL 语句为“SELECT * FROM T_Emplo

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 343,982
精华内容 137,592
关键字:

数据库判断语句