学习笔记7——数据库基础知识以及mysql的查询语句

学习笔记系列开头惯例发布一些寻亲消息

链接:https://baobeihuijia.com/bbhj/contents/3/199913.html
学习笔记7——数据库基础知识以及mysql的查询语句_第1张图片

数据库

  • 三个概念区分

    • DB:数据库,存储数据的仓库,有组织的数据容器
    • DBMS:数据库管理系统
    • SQL:几乎所有的DBMS都支持的语言
  • 对数据库的大致了解过程

    MySQL详细学习教程(建议收藏)-CSDN博客

    聚集索引(聚类索引)与非聚集索引(非聚类索引) - 知乎 (zhihu.com)

    主键约束(PRIMARY KEY)和唯一约束(UNIQUE)的区别_主键约束和唯一约束有什么区别-CSDN博客

    事务ACID理解-CSDN博客

    数据库三级模式:外模式、模式和内模式_数据库模式内模式外模式-CSDN博客

  • 基础知识

    • mysql的索引从1开始,但是分页查询是从0开始起始索引
    • 起别名,as或者空格,需要注意**【由于mysql先执行from,所以起了别名后,其他地方就不能再使用原名】**
    • mysql中+只有运算符含义,如果遇到字符串就会将字符转化为数据:转化成功继续计算,转化失败则将字符型转化为0,如果其中一个为null那么拼接结果为null
    • 字符串拼接:SELECT CONCAT(first_name,last_name) AS “name” FROM employees; 如果其中一个为null那么拼接结果为null
    • DESC departments;
    • 字段用着重符,如果是加入的字符串要用单引
    • IFNULL(字段,0) 字段为null则改为0,不为null则仍为原数据
    • 在GBK中一个字符占2个字节,utf8中一个字符占3个字节
  • 1、> < = != >= <=
    2、and or not
    3、like / between and / in / is null

  • like 用通配符% 表示任意多的字符,包括0个,下划线表示一个

    • SELECT *
      FROM employees
      WHERE first_name LIKE ‘%a%’;

      SELECT *
      FROM employees
      WHERE first_name LIKE ‘__e__a%’;

      SELECT *
      FROM employees
      WHERE last_name LIKE ‘__%’

  • between

    • 两边都是闭区间、有前后关系

      SELECT *
      FROM employees
      WHERE employee_id BETWEEN 100 AND 120;

  • IN: 表示某字段是否满足in列表中的一项,in中的判断逻辑是:是否能找到直接相等?

    • SELECT *
      FROM employees
      WHERE job_id IN (‘IT_PROG’,‘AS_VD’);
  • IS NULL:等号不能判断null, <=>安全等于符号

    • SELECT *
      FROM employees
      WHERE commission_pct IS NULL;
    • SELECT *
      FROM employees
      WHERE commission_pct IS NOT NULL;
  • 排序查询

    • 默认为升序、ASC \ DESC

    • 一般放在查询的最后边

    • SELECT *,salary*12*(1+IFNULL(commission_pct,0)) AS money
      FROM employees
      ORDER BY money DESC;
      
      # 按照多个条件进行排序
      SELECT *
      FROM employees
      ORDER BY salary DESC, employee_id;
      
  • 常见函数

    • 单行函数:concat / length / ifnull / UPPER / LOWER (变化大小写) / substr(截取字符串) / instr(返回第一次出现的起始索引),trim是去掉左右空格,lpad

      # 返回第一次出现的起始索引
      SELECT INSTR('zhuahdhqwdhqwo','hq');
      # 可以选择去前或者去后
      SELECT TRIM('a' FROM 'aaaazhiyaaaaaaa');
      # lpad进行左长度填充,超过固定长度就会截断
      SELECT LPAD('yyy',10,'-');
      # rpad右填充
      SELECT RPAD('yyy',10,'-');
      # replace
      SELECT REPLACE('nihaowoshiczy','czy','dameinv');
      
      # round:四舍五入
      SELECT ROUND(4.5);
      SELECT ROUND(1.657,2);
      
      # ceil:向上取整,返回大于等于本身的最小整数
      
      # floor:向下取整,返回小于等于本身的最小整数
      
      # truncate 截断
      SELECT TRUNCATE(1.666666,3);
      
      #mod取余,结果只看被除数的正负号: mod(a,b)  =  a-a/b*b
      
      #时间转换 STR_TO_DATE
      SELECT STR_TO_DATE('7-31 2023','%c-%d %Y');
      SELECT DATE_FORMAT(NOW(),'%Y  %c_%d');
      
      select version();
      select database();
      
      # 查询时间之差
      SELECT DATEDIFF(NOW(),'2000-7-31');
      
    • 流程控制函数

      # if
      SELECT IF(commission_pct IS NULL,'A','B') FROM employees;
      
      # case当作switch使用
      SELECT salary, department_id, 
      CASE department_id
      WHEN 30 THEN salary*1.1
      WHEN 40 THEN salary*1.2
      WHEN 50 THEN salary*1.3
      ELSE salary
      END 
      FROM employees;
      
      # case当作if else使用
      SELECT salary,
      CASE
      WHEN salary >20000 THEN 'A'
      WHEN salary >15000 THEN 'B'
      WHEN salary >10000 THEN 'C'
      ELSE 'D'
      END
      FROM employees;
      
    • 分组函数:max / min / avg / sum / count 和分组函数一起查询的字段需要和分组函数结果一致

      sum和avg不计算考虑null
      max和min也忽略考虑null
      count计算的是非空字段的数量
      
      SELECT COUNT(*) FROM employees;
      SELECT COUNT(1) FROM employees;
      
  • 查询

    • 分组查询

      SELECT MAX(salary),job_id
      FROM employees
      GROUP BY job_id;
      
      
      SELECT COUNT(*), department_id
      FROM employees
      GROUP BY department_id
      HAVING COUNT(*)>2;
      
      # 查询每个工种有奖金的最高工资大于12000的工种和最高工资
      SELECT job_id, MAX(salary)
      FROM employees
      WHERE commission_pct IS NOT NULL
      GROUP BY job_id
      HAVING MAX(salary)>12000;
      
      # 查询领导编号大于102的每个领导下最低工资大于5000的领导编号和最低工资
      SELECT manager_id, MIN(salary)
      FROM employees
      WHERE manager_id > 102
      GROUP BY manager_id
      HAVING MIN(salary)>5000;
      
      # 多个字段分组
      SELECT AVG(salary), department_id, job_id
      FROM employees
      GROUP BY department_id, job_id;
      
      # 多个字段分组查询
      SELECT AVG(salary), department_id, job_id
      FROM employees
      WHERE department_id IS NOT NULL
      GROUP BY department_id, job_id
      HAVING AVG(salary)>10000
      ORDER BY AVG(salary) DESC;
      
    • 连接查询:sql92和sql99语法

      # sql92语法内连接语法:
      
      # 等值连接:产生交集部分
      SELECT `name`,boyname FROM beauty, boys
      WHERE beauty.`boyfriend_id` =  boys.`id`;
      
      SELECT department_name,d.manager_id,MIN(salary)
      FROM departments d, employees e
      WHERE e.`department_id` = d.`department_id` AND e.`commission_pct` IS NOT NULL
      GROUP BY department_name,d.manager_id;
      
      # 非等值连接
      SELECT salary, grade_id
      FROM employees,job_grade
      WHERE salary BETWEEN lowerst_sal AND highest_sal;
      
      # 自连接
      SELECT a.`employee_id`, b.`employee_id`
      FROM employees a, employees b
      WHERE a.`manager_id` = b.`employee_id`;
      
      
      SELECT country_id, COUNT(*)
      FROM departments d,locations l
      WHERE d.`location_id` = l.`location_id`
      GROUP BY l.`country_id`
      HAVING COUNT(*)>2;
      
      # sql99内连接语法
      #inner join
      SELECT last_name,department_name
      FROM employees e
      INNER JOIN departments d
      ON e.`department_id` = d.`department_id`;
      
      # 三表连接
      SELECT last_name,department_name,job_title 
      FROM employees e
      INNER JOIN departments d
      ON e.`department_id` = d.`department_id`
      INNER JOIN jobs j
      ON e.`job_id` = j.`job_id`
      ORDER BY department_name;
      
      # 非等值连接
      # 自连接
      SELECT e.last_name,m.last_name
      FROM employees e
      INNER JOIN employees m
      ON e.`manager_id` = m.`employee_id`
      WHERE e.`last_name` LIKE '%k%';
      
      # 外连接,用于查询一个表中有另一个表中没有,结果为主表的全部记录
      # 包括两部分:内连接(只要有相等就会显示) + 主表有但是从表没有的显示为null(筛选的时候用从表的主键)
      # 左外和右外交换表的顺序,可以实现同样的结果
      # 一般是为了查询除了交集部分的不匹配的行
      
      # left outer  right outer
      SELECT `name`,boys.*
      FROM beauty
      LEFT OUTER JOIN boys 
      ON beauty.`boyfriend_id` = boys.`id`
      WHERE boys.id IS NOT NULL;
      
      SELECT department_name
      FROM departments d
      LEFT OUTER JOIN employees e
      ON d.department_id = e.department_id
      WHERE e.employee_id IS NULL;
      
      
      # 查询部门名为SAL或者IT的员工信息,防止出现SAL部门没有员工
      SELECT e.*
      FROM employees e
      RIGHT OUTER JOIN departments d
      ON e.`department_id` = d.`department_id`
      WHERE d.`department_name`= 'SAL' OR d.`department_name` = 'IT';
      
      # full outer join,除了内连接结果,保留左和右边没有匹配的部分
      
      # 交叉连接:就是笛卡尔乘积
      SELECT `name`, boyname
      FROM beauty
      CROSS JOIN boys;  
      
    • 子查询

      # 有了子查询后尽量不要用两表连接筛选了
      # 如果是select嵌套select那么成为外查询/主查询
      
      # 子查询,结果集为一个标量值
      # where后边加select
      SELECT last_name,job_id,salary
      FROM employees
      WHERE salary=(
      	SELECT MIN(salary)
      	FROM employees
      );
      
      # having后边加select
      SELECT department_id,MIN(salary)
      FROM employees
      GROUP BY department_id
      HAVING MIN(salary)>(
      	SELECT MIN(salary)
      	FROM employees
      	WHERE department_id = 50
      );
      
      in/not in:可以改写为 =any / !=all
      ANY
      ALL
      
      # select后边加select
      # 查询是一条一条进行遍历的,所以在select后边的查询必须是一行一列
      SELECT d.*,(
      	SELECT COUNT(*)
      	FROM employees e
      	WHERE e.department_id = d.department_id
      )FROM departments d;
      
      # from后边加select,必须给新表起别名
      SELECT ag_dep.*, jg.level
      FROM
      (
      	SELECT AVG(salary) ag,department_id
      	FROM employees
      	GROUP BY department_id
      ) ag_dep INNER JOIN job_grades jg
      ON ag_dep.ag BETWEEN jg.lowest_sal AND jg.highest_sal
      
      # exist
      SELECT d.department_name
      FROM departments d
      WHERE d.department_id IN (
      	SELECT e.department_id
      	FROM employees e
      );
      
      SELECT d.department_name
      FROM departments d
      WHERE EXISTS(
      	SELECT *
      	FROM employees e
      	WHERE e.`department_id` = d.`department_id`
      );
      
      SELECT bo.*
      FROM boys bo
      WHERE EXISTS(
      	SELECT *
      	FROM beauty b
      	WHERE b.`boyfriend_id`  = bo.`id`
      );
      
      SELECT bo.*
      FROM boys bo
      WHERE bo.`id`  IN (
      	SELECT b.`boyfriend_id`
      	FROM beauty b
      );
      
    • 分页查询

      # 分页查询
      limit offset,size;
      offset:要显示的起始索引,从0开始
      size:要显示的条目数
      
      # 分页公式:
      limit (page-1)*size,size;
      
      SELECT *
      FROM employees
      WHERE commission_pct IS NOT NULL
      ORDER BY salary DESC
      LIMIT 10;
      

      学习笔记7——数据库基础知识以及mysql的查询语句_第2张图片

      # 一个经典的样例
      # 查平均工资最高的部门的manager的信息
      # 两个表的不同拼接会是不同结果
      (
      如果是employee的department_id和department的department_id拼接,那么得到的结果是我们知道每个员工的部门详细信息
      但是如果是employee的employee_id和department的manager_id拼接,那么得到的是我们知道每个部门领导人的详细信息
      )
      
      SELECT *
      FROM employees e
      INNER JOIN departments d
      ON e.`employee_id` = d.`manager_id`
      WHERE d.`department_id` = (
      	SELECT  department_id
      	FROM employees
      	GROUP BY department_id
      	ORDER BY AVG(salary) DESC
      	LIMIT 1
      );
      
    • 联合查询

      union 连接两个查询结果:查询结果来自于多个表,表之间没有连接关系,但是查询结果列数和列类型要一致 
      union all:可以包含两个表中的重复项
      

你可能感兴趣的:(数据库,学习,笔记)