Database-3:SQL语句之DQL

〇、前言

    DQL(Data Query Language):数据查询语言,用来操作表中存储的数据,但是只能完成查。

一、MySQL查询语句

        SELECT selection_list /*要查询的列名称,多个字段名称使用‘,’隔开,‘*’表示查询所有列*/
        FROM table_list /*要查询的表名称*/
        WHERE condition /*行条件*/
        GROUP BY grouping_columns /*对结果分组*/
        HAVING condition /*分组后的行条件*/
        ORDER BY sorting_columns /*对结果排序*/
        LIMIT offset_start, row_count /*结果限定,即分页*/ (LIMIT仅MySQL、SQLite使用)

    1、基础查询

  • 查询所有数据行的所有列: SELECT * FROM [表名] ;(注意:检索不需要的列通常会降低检索速度和应用程序的性能)
  • 查询所有数据行的指定列: SELECT 列名1 , 列名2 , ... FROM [表名] ;

        注意:如果没有明确排序查询结果,则返回的数据没有特定的顺序。

    2、WHERE条件查询

  • =(等于)、!=(不等于)、<>(不等于)、<(小于)、<=(小于等于)、!<(不小于,即大于等于)、>(大于)、>=(大于等于)、!>(不大于,即小于等于);
  • BETWEEN…AND…(在…到…之间的所有数据,包括开始值和结束值);
  • IN(set)(在set里面的)、NOT IN (set)(不在set里面的);    ( IN 与 OR 类似,NOT IN 与 AND 类似)
  • IS NULL(空不能使用 = 或者 != 进行判断,需要使用 is null 或者 is not null )    (注意:在进行匹配过滤或非匹配过滤时,不会返回NULL值的行);
  • AND(逻辑操作符:并且);    (SQL在处理 OR 操作符前,优先处理 AND 操作符)
  • OR  (逻辑操作符:或者);    (许多 DBMS 在OR子句的第一个条件得到满足的情况下,就不再计算第二个条件了)
  • NOT(否);                             (NOT 操作符有且只有一个功能,那就是否定其后所跟的任何条件,它总是与其他操作符一起使用,从不单独使用)

    3、模糊查询:SELECT 列名1 , 列名2 , ... FROM [表名] WHERE [字段名] LIKE '值' ;

        通配符:(通配符搜索只能用于文本字段即字符串)、(通配符搜索一般比其他搜索要更耗时)。

  •     _ 匹配任意单个字符(1 个字符,DB2 不支持)
  •    % 匹配任意多个字符(0 个、 1 个或多个字符)
  •    []  匹配方括号中任意单个字符(可以用前缀脱字号字符^来否定)(除 SQL Server 外其余大都不支持)
SELECT * FROM emp WHERE ename LIKE '%M%'; 

-- _: 表示匹配任意单个字符
-- %: 表示匹配任意多个字符

-- 查询ename由4个字母组成的员工的数据
SELECT * FROM emp WHERE ename LIKE '____' ;

-- 查询ename由M开始的员工的数据
SELECT * FROM emp WHERE ename  LIKE 'M%' ;

    4、去除重复:DISTINCT (在SELECT之后 列名之前,作用于所有的列)

    5、字段运算(计算字段):

        拼接字段:SQL Server 使用+号; DB2、 Oracle、 PostgreSQL 和 SQLite 使用 ||;MySQL 和 MariaDB 中,必须使用Concat函数。

        算术计算:SQL 支持基本算术操作符加(+)、减(-)、乘(*)、除(/),此外圆括号可用来区分优先顺序。

        Trim:RTRIM()函数去掉值右边的所有空格,LTRIM()函数去掉字符串左边的空格, TRIM()函数去掉字符串左右两边的空格。

        null 参与的运算结果都是null;如果是 null 我们就认为是0:IFNULL(字段名称 , 要取的值)

        如:SELECT * , sal + IFNULL(comm , 0) FROM emp ;

-- null在参与运算的时候结果都是null
-- ifnull(字段名称 , 值)
SELECT * , sal + comm FROM emp ;
SELECT * , sal + IFNULL(comm , 0) FROM emp ;

-- as 关键字用来起别名
SELECT * , sal + IFNULL(comm , 0) AS income FROM emp ;

    6、别名:使用 AS 关键字(列和表都可以使用AS关键字起别名;也都可以省略AS关键字,直接跟别名)

        如:SELECT * , sal + IFNULL(comm , 0) AS income FROM emp ;

    7、排序:ORDER BY [要排序的字段] ASC(升序)/DESC(降序)

  • ASC升序指从 A 到 Z,DESC降序指从 Z 到 A;且ASC和DESC关键字只应用到直接位于其前面的列名。
  • 如果按照升序排序ASC可以省略;
  • ORDER BY 后面可以跟多个排序字段,多个排序字段之间使用‘,’隔开。(如:SELECT * FROM emp ORDER BY sal DESC , comm ASC ;)
  • ORDER BY 还支持按相对列位置进行排序。(如:SELECT prod_id, prod_price, prod_name FROM products ORDER BY 2, 3 ;)

    8、函数

    9、聚合函数:用来做纵向运算的函数(SELECT [聚合函数] FROM  [表名])

  • COUNT():统计指定列不为NULL的记录行数;如:COUNT(列名)、COUNT(*)、COUNT(1),建议使用COUNT(1);
  • MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;如:MAX(列名);
  • MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;如:MIN(列名);
  • SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;如:SUM(列名);
  • AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;(其实是通过对表中行数计数并计算其列值之和求得平均值)如:AVG(列名);
-- 查询总共有多个员工
-- count: 不会计算包含null的值
SELECT COUNT(*) FROM emp ;
SELECT COUNT(1) FROM emp ;
SELECT COUNT(empno) FROM emp ;
SELECT COUNT(comm) FROM emp ;

-- 查询工资最大的值
-- max
SELECT MAX(sal) FROM emp ;

-- 查询工资最小的值
-- min
SELECT MIN(sal) FROM emp ;

-- 查询平均工资
-- avg
SELECT AVG(sal) FROM emp ;

-- 查询工资总和
-- sum
SELECT SUM(sal) FROM emp ;

    10、分组查询:把多条数据归为一组(SELECT [分组字段]/[聚合函数] FROM  [表名] GROUP BY 分组字段); 

  • 在分组以后 , 查询的字段只能是分组字段或者聚合函数(因为分组以后,其他字段在组内没有共同值了(查询也没有意义),只有分组字段在组内是同一个值)
  • 在分组之前对结果进行限定,使用where子句(针对每一条数据的过滤使用WHERE)
  • 在分组之后对结果进行限定,使用having子句(针对每一组数据的过滤使用HAVING)
-- group by 分组字段
-- 需求: 查询每一个部门的工资总和
SELECT deptno , SUM(sal) FROM emp GROUP BY deptno ;

-- 需求: 查询每个部门的部门编号以及每个部门的人数
SELECT deptno , COUNT(1)  FROM emp GROUP BY deptno ;

-- 需求: 查询每个部门的部门编号以及每个部门工资大于1500的人数
-- 首先查询工资大于1500的员工信息 , 在按照部门编号进行分组
SELECT deptno , COUNT(1) FROM emp WHERE sal > 1500 GROUP BY deptno ;

-- 查询工资总和大于9000的部门编号以及工资和
-- 先分组然后进行过滤的时候不能使用where , 需要使用having
SELECT deptno , SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal) > 9000 ;

    11、限定行数:各种数据库实现不相同

  • SELECT TOP [n] [列名] FROM [表名] ;(SQL Server)只检索前n行数据,即最多返回n行数据;
  • SELECT [列名] FROM [表名] FETCH FIRST [n] ROWS ONLY ;(DB2)只检索前n行数据;
  • SELECT [列名] FROM [表名] WHERE ROWNUM <= [n] ;(Oracle)只检索前n行数据,ROWNUM是行计数器;
  • SELECT [列名] FROM [表名] LIMIT [n] ;(MySQL、MariaDB、PostgreSQL、SQLite)只检索前n行数据,即最多返回n行数据;

    12、分页查询:

    MySQL分页:SELECT [列名] FROM [表名] LIMIT [每一页的行数] OFFSET [开始的记录角标] ; 或:SELECT [列名] FROM [表名] LIMIT 开始的记录角标, 每一页的条数 ;(反着的,要小心)

        注意:开始的记录角标从0开始,所以开始的记录角标 = (页码 - 1) * 每一页的条数 ;

        理解:对于公式,比如需要显示第100页的数据,那么前面已经显示了99页,每页5条的话,已经显示了99*5=495条数据,标号从0开始,那么前面的数据标号(角标)是0-494,所以第100页的开始的标号是495,即(100-1)*5。

    SQL Server分页:

SELECT [列名] FROM ( 
SELECT ROW_NUMBER() OVER ( ORDER BY [排序字段] ) AS ROW, * FROM [表名] 
) AS T
WHERE T.ROW BETWEEN [开始行号] AND [结束行号] ;

        注意:SQL Server的行号从1开始,所以开始行号 = (页码 - 1)  * 每一页的条数 + 1;

猜你喜欢

转载自blog.csdn.net/beita08/article/details/112158061