java 数据库 查询 select

查询所有字段
-- 查询所有列:select * from 表名(*:是通配符,表示所有列)  
select * from employees

查询部分字段
 select 列名1,列名2,... from 表名

-- 查询所有字段
SELECT * from employees
-- 查询员工id、员工工资
select employee_id,salary from employees
-- 列出所有字段名查询所有字段
select employee_id,salary,first_name,last_name,email,phone_number,job_id,commission_pct,manager_id,department_id,hiredate from employees

结果运算
+、-、*、/、%
select 列名 运算符 值  from 表名
-- 查询员工id和工资,及对工资进行加减乘除的运算
    select employee_id,salary,salary+100,salary-100,salary*100,salary/100,salary%100  from employees

别名
#### 别名

- 对查询之后的结果起别名

~~~sql
    select 列名 as 别名,列名 as 别名,列名,...  from 表名
~~~

- 别名可以省略单引号

  > 标准SQL中没有双引号,字符串通过单引号修饰

- as关键字可省

~~~sql
    -- 查看员工id和员工工资
   select employee_id as 员工id,salary as 工资 from employees
    -- as关键字可省
   select employee_id 员工id,salary 工资 from employees
~~~

#### 去重

~~~sql
select distinct 列名1,列名2,.. from 表名
~~~

- 当去重规则为多个字段时,只有当多个字段的值都相同时才会去重

~~~sql
-- 查询所有的职位id(根据job_id进行去重)
select distinct job_id from employees
-- 查询所有的职位和部门id(根据job_id和department_id去重)
select distinct job_id,department_id from employees
~~~

#### 分支-case when

~~~sql
case
   when 条件1 then 结果1
   when 条件2 then 结果2
   ...
   else 其他结果
end
-- 满足when中的条件,便执行对应then中的结果,如果when都不满足,则最终执行else,从上往下判断
~~~

~~~java
-- 查询员工id、员工工资、工资等级(工资>=15000 高薪,工资>=10000 中薪,工资>=5000  一般,工资<5000  低薪)
select employee_id 员工id,salary 员工工资,
	case
		when salary>=15000 then '高薪'
		when salary>=10000 then '中薪'
		when salary>=5000 then '一般'
		else '低薪'
	end  as 薪资等级
from employees
~~~

#### 查看表详情

- 表详情:当前表的字段设计

~~~sql
describe 表名-- describe关键字可以简写为desc
~~~

~~~sql
-- 查看员工表详情
describe employees
desc employees
~~~










### 条件查询

- 能够支持的关系运算符:>  <   >=   <=  !=  =

#### 单条件查询

~~~sql
select 列名... from 表名  where 筛选条件
~~~

- MySQL中对比字符串时默认不区分大小写,若想区分,则在对应字段前添加binary关键字即可

~~~sql
-- 查询工资大于10000的员工信息
select * from employees where salary>10000
-- 查询部门id<50的员工信息
select * from employees where department_id<50
-- 查询起始名为Steven的员工信息-不区分大小写
select * from employees where first_name='steven'
-- 区分大小写
select * from employees where binary first_name='Steven'
~~~

#### 多条件查询

~~~sql
where 条件1 连接符  条件2
~~~

~~~sql
连接符:
and:表示并且,意为同时满足,相当于Java中的&&
or:表示或者,意为满足任意一个即可,相当于Java中的||
~~~

~~~sql
-- 查询员工工资>10000并且部门id<50的员工信息
select * from employees where salary>10000 and department_id<50
-- 查询员工id<120或者部门id=80的员工信息
select * from employees where employee_id<120 or department_id=80
~~~

#### 区间查询

~~~sql
where 列名 [not] between 起始值 and 结束值
~~~

- 中括号中的内容意为可省
- 加上not表示不在此区间之内

~~~sql
-- 查询工资大于10000并且小于12000的员工信息
select * from employees where salary>=10000 and salary<=12000
-- 区间查询(在范围内):between 起始值 and 结束值
select * from employees where salary between 10000 and 12000
-- 区间查询(不在范围内):not between 起始值 and 结束值
select * from employees where salary not between 10000 and 12000
~~~

#### 枚举查询

~~~sql
where 列名 [not] in(值1,值2,...)
~~~

~~~sql
-- 查询部门id是10、20、30的员工信息
select * from employees where department_id=10 or department_id=20 or department_id=30
-- 枚举查询(列举字段所有满足条件的值):列名 in(值1,值2,...)
select * from employees where department_id in(10,20,30)
-- 不在范围内:列名  not in(值1,...)
select * from employees where department_id not in(10,20,30)
~~~

#### 空值查询

~~~sql
where 列名 is [not] null
~~~

~~~sql
-- 查询没有绩效的员工信息
-- 为空:列名 is null
select * from employees where commission_pct is null
-- 不为空:列名 is not null
select * from employees where commission_pct is not null
~~~

#### 模糊查询

~~~sql
where 列名 [not] like '通配模式'

可用占位符:
%:表示n个字符
_:表示1个字符
~~~

~~~sql
-- 查询起始名以p开头的员工信息
select * from employees where first_name like 'p%'
-- 查询起始名中包含p的员工信息
select * from employees where first_name like '%p%'
-- 查询起始名第二个字母是a的员工信息
select * from employees where first_name like '_a%'
-- 查询起始名由5个字母组成的员工信息
select * from employees where first_name like '_____'
~~~

### 单行函数

- 一行数据得到一个结果

1. concat

   - 将多个内容合并为一个内容,相当于字符串拼接

   ~~~sql
   select concat(列名1,列名2,...) from 表名
   ~~~

   ~~~sql
   -- 以“起始名-结束名"的方式查询员工姓名
   select concat(first_name,'-',last_name) from employees
   ~~~

2. length

   - 获取数据长度

   ~~~sql
   select length(列名) from 表名
   ~~~

   - 也可用于where子句作为筛选条件

   ~~~sql
   -- 获取员工起始名长度
   select first_name,length(first_name) from employees
   -- 查询起始名长度>5的员工信息
   select * from employees where length(first_name)>5
   ~~~

3. sysdate、now

   - 获取当前系统时间

   ~~~sql
   select sysdate()|now()
   ~~~

   - dual:虚拟表,作用为语法占位,特点是从该表查询只会得到一个结果
     - from dual可省

   ~~~sql
   -- 查看当前系统时间
   select sysdate() from dual
   select now() -- from dual
   ~~~

4. mod(值1,值2):获取值1%值2的结果。标准SQL中没有%

   ~~~sql
   -- 获取10%3的结果
   select mod(10,3) 
   -- 查询所有员工工资%10000的结果
   select employee_id,salary,mod(salary,10000) from employees
   ~~~

5. date_format

   - 将日期转换为固定格式的字符串

   ~~~sql
   date_format(date,'format')
   ~~~

   - format日期格式:

     | 标识符 | 含义                  |
     | ------ | --------------------- |
     | %Y     | 年(4位)             |
     | %y     | 年(2位)             |
     | %m     | 月(格式为01-12)     |
     | %c     | 月(格式为1-12)      |
     | %d     | 天(格式为01-30\|31) |
     | %e     | 天(格式为1-30\|31)  |
     | %H     | 小时(格式为00-23)   |
     | %k     | 小时(格式为0-23)    |
     | %i     | 分钟(格式为00-59)   |
     | %s     | 秒(格式为00-59)     |

   ~~~sql
   -- 查询各个员工入职的年份
   select employee_id,hiredate,date_format(hiredate,'%Y')
   from employees
   -- 查询各个员工入职的年份和月份
   select employee_id,hiredate,date_format(hiredate,'%Y-%m')
   from employees
   ~~~

6. str_to_date

   - 将日期格式的字符串转换为日期类型

   ~~~sql
   str_to_date('日期格式的字符串','format')
   ~~~

   ~~~sql
   -- 将'2022-12-06 17:32:19'转换为对应的日期类型
   select str_to_date('2022-12-06 17:32:19','%Y-%m-%d %H:%i:%s')
   ~~~

### 排序

~~~sql
select 列名... from 表名
[where 条件]
order by 列名 排序规则

排序规则:asc(升序,默认值)|desc(降序)
~~~

#### 单列排序

- 排序规则只有一列

~~~sql
-- 根据薪资进行从高到低的排序,查看结果
select * from employees order by salary desc
-- 查询工资大于10000的员工信息并对其按照薪资升序排列
select * from employees where salary>10000 order by salary 
~~~

#### 多列排序

~~~sql
order by 列名1 排序规则1,列名2 排序规则2,...
~~~

- 规则:先根据列1排,列1相同再根据列2排,以此类推

~~~sql
-- 根据员工工资进行降序排列,如果薪资相同,再根据员工id升序排序
select * from employees order by salary desc,employee_id asc
~~~

# Day2

## 组函数

- 以组为操作单位,一组数据得到一个结果。
- 在没有手动分组的前提下,整张表默认为一组数据

1. max(列名):获取最大值
2. min(列名):获取最小值
3. sum(列名):获取总和
4. avg(列名):获取平均值
5. count(列名):统计值的个数

- **所有组函数都会自动忽略null值**

~~~sql
-- 查看员工的最高薪资
select max(salary) from employees
-- 查看员工的最低薪资、平均薪资、月薪资总和
select min(salary),avg(salary),sum(salary) from employees
-- 统计总共有多少名员工
select count(*) from employees
select count(employee_id) from employees
-- 统计员工表中部门的个数
-- 先对整张表的部门id进行去重,再count统计结果
select count(distinct department_id) from employees
~~~

## 分组

- 在某些情况下,我们需要根据需要对表中数据进行手动分组
- 规则:值相同的为同一组数据

~~~sql
select 列名 from 表名 group by 列名 
~~~

> 执行顺序:from-->group by-->select
>
> 先确定从哪张表进行操作-->对表中数据进行分组-->基于分组结果进行查询操作

~~~sql
-- 查询各个部门的平均薪资
select department_id,avg(salary) from employees group by department_id
~~~

### where+group by

- 先where,再group by

  > 先筛选出符合要求的数据,再对符合要求的数据进行分组时,分组的工作量会被减少,效率更高

~~~sql
where 条件 group by 列名
~~~

~~~sql
-- 查询部门id为10,20,30的部门的平均薪资
select department_id,avg(salary) 
from employees
where department_id in(10,20,30)
group by department_id
~~~

- 执行顺序:from-->where-->group by-->select

![](MySQL笔记.assets/where+group by.jpg)

### having子句

- 和where类似,也是用来做数据筛选,在分组之后执行

~~~sql
group by 列名 having 条件
~~~

~~~sql
-- 查询部门平均薪资>=7000的部门id
select department_id,avg(salary)
from employees
group by department_id   -- 先分组
having avg(salary)>=7000  -- 后筛选
~~~

![](MySQL笔记.assets/having.jpg)

#### 和where子句的区别

1. where在分组前执行,having在分组后执行
2. where子句存在分组时不能使用组函数,但是having可以
3. 当既可以使用where,又能使用having时,优先使用where,效率更高

## limit关键字

- 作用:限制查询结果显示的条目数,通常用于分页

~~~sql
select 列名.. from 表名
limit 显示的起始下标,显示的条数
~~~

- 使用:
  1. 该关键字是基于**查询的最终结果**进行限制显示,所以其与其他查询关键字使用时,必须最后执行,所以一定写在最后
  2. 下标为0时,可以省略不写

~~~sql
-- 查询工资最高的前十名员工信息
select employee_id,salary
from employees
order by salary desc -- 先根据工资进行降序排序
limit 0,10  -- 显示前十行

-- 查看前十条员工信息
select * from employees limit 10

-- 查询部门平均薪资最高的前3个部门id
-- 分析:
		-- 部门平均薪资:根据部门id分组 group by 
		-- 最高:根据平均薪资进行降序排序  order by avg(salary)
		-- 前三个:limit从最终查询结果中提取出前三条
select department_id,avg(salary)
from employees
group by department_id  -- 根据部门id分组
order by avg(salary) desc  -- 根据平均薪资进行降序排序
limit 3 -- 从最终查询结果中提取出前三条
~~~

## 查询关键字的顺序

- select 、 from 、where 、  order by 、  group by 、  having 、  limit

~~~sql
语法顺序:
select 、 from 、where、 group by、having 、order by 、limit
~~~



## 子查询

- 当一个SQL的执行需要借助另一个SQL的执行结果时,则需要进行SQL嵌套,该语法结构称之为子查询

~~~sql
select 列名... from 表名 where 列名 =|in (子SQL语句)
~~~

- 执行顺序:优先执行小括号内的子SQL,根据子SQL的执行结果再执行外层SQL
- 只要逻辑完整,对SQL的嵌套层数不做要求
  - 执行:从内向外执行

### where单值子查询

- 子SQL(被嵌套的SQL)返回的时一行一列的单个结果

~~~sql
-- 查询员工id为101号员工的领导信息
-- 先查询员工id为101号员工的直接领导的id
select manager_id from employees where employee_id=101
-- 拼装
select * from employees
where employee_id=(select manager_id from employees where employee_id=101
)

-- 查询员工id为100的员工所在的部门信息
-- 查询员工id为100的员工所在的部门id
select department_id from employees where employee_id=100
-- 拼装
select * from departments
where department_id =(select department_id from employees where employee_id=100)
~~~

### where多值子查询

- 子SQL返回的是多个结果

~~~sql
-- 查询工资>10000的员工所在的部门信息
select * from departments 
where department_id in(select department_id from employees where salary>10000) 
~~~

### from子查询(了解)

- 将子SQL的查询结果临时看作一张表进行后续操作
- 为了符合语法要求,需要给子查询的结果起别名充当临时表的表名

~~~sql
-- 查询工资最高的前十名员工的总薪资

-- 分析:1. 把工资最高的前十名员工的薪资查出来
			-- 2. 对这十个工资进行求和
-- 查询SQL的基本语法:select 列名 from 表名
select sum(salary) 
from (select salary from employees order by salary desc limit 10) as e

-- 子SQL:把工资最高的前十名员工的薪资查出来
select salary from employees order by salary desc limit 10
~~~

## 表连接

> 关系字段:两表中有关联关系的字段

![](MySQL笔记.assets/关系字段.jpg)

- 什么是表连接?
  - 当我们的查询结果需要从多张表中获取时,此时应该让表之间建立连接,同时获取数据

### 内连接

- 特点:同时对连接双方做约束,双方只有符合连接条件的数据才会进行显示

~~~sql
select 表名.列名, 表名.列名,...
from 表名1 inner join 表名2
on 连接条件  -- 两表间的关系字段
~~~

~~~sql
-- 查询员工的id、工资与部门名称
	-- 第一步:确定数据来自于哪些表
	-- 第二步:确定两表之间的关系字段
	-- 书写表连接完成查询操作

select  e.employee_id 员工id,e.salary 员工工资,d.department_name  -- 基于连接结果进行查询操作
from employees e inner join departments d -- 起别名,方便后续书写
on e.department_id=d.department_id -- 关系字段:员工表的部门id=部门表的部门id
~~~

> from-->join on:确定数据来源
>
> select:查询操作

![](MySQL笔记.assets/内连接.jpg)

### 左外连接

- 特点:左表中的数据无论如何都会显示,右表中的数据只有符合连接条件才会显示

~~~sql
select 表名.列名, 表名.列名,...
from 左表 left outer join 右表
on 连接条件  -- 两表间的关系字段
~~~

~~~sql
-- 使用左外连接显示员工信息及其部门信息
select e.*,d.*
from employees e left outer join departments d -- 员工信息无论如何都会显示,部门信息符合连接条件才会显示
on e.department_id=d.department_id
~~~

![](MySQL笔记.assets/左外连接.jpg)

### 右外连接

- 特点:右表中的数据无论如何都会显示,左表中的数据只有符合连接条件才会显示

~~~sql
select 表名.列名, 表名.列名,...
from 左表 right outer join 右表
on 连接条件  -- 两表间的关系字段
~~~

~~~sql
-- 使用右外连接显示部门信息及对应员工信息
select  e.*,d.*
from employees e right outer join departments d
on e.department_id=d.department_id
~~~

> 连接关键字中的inner、outer可以省略

![](MySQL笔记.assets/右外连接.jpg)

### 全外连接(了解)

- 特点:对双方都不做约束
- 作用:将两个查询结果进行合并

~~~sql
查询结果1 union 查询结果2
~~~

- 使用:
  1. 合并双方字段数目、内容必须一致
  2. union关键字可以去重
  3. union all 不会对结果去重

~~~sql
-- 查询员工表所有信息
select employee_id,first_name,salary from employees
union all -- 合并,不去重
-- 查询员工表所有信息
select employee_id,first_name,salary from employees
~~~

### 自连接

- 特点:是特殊的表连接,参与连接的是同一张表

- 使用:

  - 表中的两个字段为关系字段,作为连接条件

    ~~~sql
    -- 按照指定要求查询员工信息:员工id,员工姓名,直接领导的id,直接领导的姓名
    select e1.employee_id 员工id,e1.first_name 员工姓名,e1.manager_id 领导id,e2.first_name 领导姓名
    from employees e1 left join employees e2 -- e1:员工信息  e2:领导信息
    on e1.manager_id=e2.employee_id  -- 连接条件:员工的领导id=领导的员工id
    ~~~

  - 连接双方判断同一字段,作为连接条件

    ~~~sql
    -- 查询工资相同的员工id及其工资
    select e1.employee_id,e1.salary,e2.employee_id,e2.salary
    from employees e1 left join employees e2 -- 连接参与比较的两个员工
    on e1.salary=e2.salary -- 两个员工的工资相同
    where e1.employee_id>e2.employee_id
    ~~~

> 1. 如果查询字段来自于多张表,内连接或左外连接
> 2. 如果查询字段来自于一张表并且来自同一行数据,则简单查询|子查询
> 3. 如果查询字段来自于一张表但是不来自于同一行数据。则自连接

### 多表连接

- 特点:同时从多张表中获取数据

~~~sql
select 表名.列名, 表名.列名,...
from 表1 left join 表2
on 连接条件  -- 表1和表2的关系字段
left join 表3
on 连接条件  -- 表1和表3的关系字段|表2和表3的关系字段
~~~

~~~sql
-- 查询员工id,员工姓名,所属部门id,部门名称,部门所在城市
select e.employee_id,e.first_name,d.department_id,d.department_name,l.city
from employees e left join departments d  -- 先让员工表和部门表建立连接
on e.department_id=d.department_id  -- 员工的部门id=部门的id
left join locations l  -- 再让地址表参与连接
on d.location_id=l.location_id  -- 部门表的地址id=地址表的id
~~~

> 实际开发中,不建议表连接超过3张表,否则会有性能问题

![](MySQL笔记.assets/多表连接.jpg)

# Day3

## SQL的分类

1. DQL:数据库查询语言,进行查询操作的SQL
2. DCL:数据库控制语言,对数据库用户进行权限设定和更改的SQL
3. DDL:数据库定义语言,进行库、表、视图、索引等创建和销毁的SQL
4. DML:数据库操作语言,对数据进行增删改的SQL
5. TCL:事务控制语言,控制事务操作的SQL

> DCL:通常由数据库超级管理员操作

你可能感兴趣的:(数据库,java,oracle)