from --> where -- > group by -- > having -- > select -- > order by -- > limit
筛选的字段名称
后面跟数据库名称
条件筛选
select distinct name, age select count(distinct name)
order by age desc # 年龄倒序 order by age asc # 年龄升序
offset 跳过多少页 limit 限制多少条数据 用于SQL查询最后使用 select name from table order by age asc limit 1
group by 用于数据分组展示 select name from table group by name
一般和 group by 连用 group by having 用于 数据 筛选 group by name having name = 'zs'
求和函数 sum() 平均值函数 avg() 中位数函数 median() 标准差函数 stddev() 求最大值函数 max() 求最小值函数 min() 计数函数 count() 类型转换函数 cast(字段名 AS 格式类型 ) 日期格式转换函数 date_format(date,'%Y %m %d %H:%i %s') 返回统计的年份 select YEAR('2020-10-10') from table 返回统计的月份 MONTH() 返回统计的天 DAY() 返回小时值 HOUR() 返回分钟值 MINUTE() 返回秒数 SECOND() 全年第几周 WEEK() 取年-月-日函数 DATE() 计算时间差函数,interval代表指定的单位,常用可选: timestampdiff(interval,start_time,end_time) YEAR 年数 MONTH 月数 DAY 天数(返回秒数差除以3600*24的整数部分) HOUR 小时(返回秒数差除以3600的整数部分) MINUTE 分钟(返回秒数差除以60的整数部分) SECOND 秒 两个日期相减,返回天数,大的值在前 datediff(end_time,start_time) 两个日期相减,返回 time 差值(时分秒格式),大的值在前 timediff(end_time,start_time) 百分比格式表示 CONCAT(字段名,'%') 替换函数 replace(字符串,原字符,新字符) 字符串的截取函数 substring(字符串,起始位置,截取字符数) 四舍五入函数 Round() --将数值四舍五入为指定数值,用法:Round(数值,返回的小数位)
row_number() # 1 2 3 4 select s_id,avg(score) as '平均成绩', row_number() over(order by avg(score) DESC) as '排名' from sc rank() # 1 2 2 4 select *, rank() over(PARTITION by c_id order by score desc) as '排名' from sc dense_rank() # 1 2 2 3 Lag() 求当前行的前 N 行 #用来计算 与前一天相比 新增的销售额 select (nowTime - (lag(nowTime, 1) over(PARTITION by c_id order by score desc)) ) Lead() 求当前行之后第 N 行对应的字段的值 select *,Lead(score,3) over(PARTITION by c_id order by score desc) as '排名' from sc
left right inner outer
select emp_no from employees where emp_no not in (select emp_no from dept_manager)
1.% (任意字符) 的用法 查询名字以 网结尾的 %占位符表示0个或多个字符,可放在查询条件的任意位置 select name from table where name like '%网' 2._的用法 查询四个字符,并且是以 abc结尾 _占位符表示一个字符,可放在查询条件的任意位置用法和%类似 select str from table where name like '_abc' 3.[ ] 指定范围 ([a-f]) 或集合 ([abcdef]) 中的任何单个字符 like’[CK]ars[eo]n’ 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。 like’[M-Z]inger’ 将搜索以字符串 inger 结尾、以从 M 到 Z 的任何单个字母开头的所有名称(如 Ringer)。 4.[^] 不属于指定范围 ([a-f]) 或集合 ([abcdef]) 的任何单个字符 like’M[^c]%’ 将搜索以字母 M 开头,并且第二个字母不是 c 的所有名称(如MacFeather)。 5.* 它同于DOS命令中的通配符,代表多个字符 c*c代表cc,cBc,cbc,cabdfec等多个字符。 6.?同于DOS命令中的?通配符,代表单个字符 b?b代表brb,bFb等
SELECT * FROM table_name WHERE date_column BETWEEN '1998-01-01' AND '2020-01-01';
*not - in
select emp_no from employees where emp_no not in (select emp_no from dept_manager)
select age from table where age > 10 or age < 5
select if(score>60, '及格', '不及格') as 标准 from table
sum() 求和 max() 最大值 min() 最小值 count() 计数 avg() 平均值 median() 中位数 stdev() 标准差
select name, case when home = 'beijing' then 'shoudu' case when home = 'beijing' then 'shoudu' end as shoudu_yes from table
SQL的分组查询可以通过使用GROUP BY子句来进行。 在MySQL中,默认情况下,如果SELECT语句包含了非聚合列(没有被聚合函数处理) 而不是所有的列都在GROUP BY子句中指定,则会引发错误。这种模式称为"严格模式"。
-- student 学生表 -- s_course 选课关系表 -- course 课程表 查询同时选修了 Java基础和高等数学这两门课程,并且Java基础成绩高于高等数学的学生信息 --临时表 with tl as ( select s.sno, s.sex, s.sname, sc.mark from student s, s course sc, course c where s.sno = sc.sno and sc.cno = c.cno and c.cname ='java基础' ), t2 as ( select s.sno, s.sname, sc.mark from student s, s course sc, course c where s.sno = sc.sno and sc.cno = c.cnoand c.cname = '高等数学' ) select t1.sno, t1.sname, t1.sex from t1, t2 where t1.sno = t2.sno and t1.mark > t2 .mark;
select b.* from age_table as a, age_table as b where a.age = 12 and b.name = 'zs' ------------------------------------------- select a.ename, (select ename from emp as b where b.empno = a.mgr ) as manager from emp as a
SELECT * FROM table_name WHERE column_name IS NULL; SELECT * FROM table_name WHERE column_name IS NOT NULL;
exists 子查询 基本语法 where exists(查询语句) // 根据查询的结果进行判断,如果结果存在就返回 1 ,否则就返回 0 --- 求出,有学生所在的班级 select * from my_class as c where exists (select stu_id from my_student as s where s.class_id = c.class_id)
文本 | 时间函数
文本函数
substring()函数
字符串的截取:substring(字符串,起始位置,截取字符数)
concat()字符串拼接
语法:concat(字符串1,字符串2,…)
replace() 替换函数
语法:replace(字符串,原字符,新字符)
时间函数
1.SQL195 查找最晚入职员工的所有信息
找出最晚入职,就是找出最近的入职员工
order by hire_date desc 字段倒序
limit 1
select * from employees order by hire_date desc limit 1 select * from employees where hire_date = (select max( hire_date ) from employees )
使用了 子表查询
窗口函数 dense_rank() over(order by hire_date desc) # 1 2 2 3
select emp_no, birth_date, first_name, last_name,gender, hire_date from (select *, dense_rank() over(order by hire_date desc) as n from employees where n = 3 )
联表查询内连接
排序
select s.emp_no emp_no, s.salary salary , s.from_date from_date , s.to_date to_date, d.dept_no dept_no from salaries s join dept_manager d on s.emp_no = d.emp_no order by s.emp_no asc;
表查询的左连接
select e.last_name last_name , e.first_name first_name , d.dept_no dept_no from dept_emp d left join employees e on d.emp_no = e.emp_no
左表查询
select e.last_name last_name, e.first_name first_name, d.dept_no dept_no from employees e left join dept_emp d on d.emp_no = e.emp_no
group by 字段 having 字段
count(字段)
select emp_no , count(emp_no) t from salaries group by emp_no having count(emp_no) > 15;
distinct salary 去重
order by salary desc 排序
select distinct salary from salaries order by salary desc
not in()
子查询 select emp_no from dept_manager
select emp_no from employees where emp_no not in (select emp_no from dept_manager)
内连接查询
select d.emp_no emp_no, de.emp_no manager from dept_emp d inner join dept_manager de on d.dept_no = de.dept_no where d.emp_no != de.emp_no
子表查询
内连接
窗口函数 rank( ) # 1 2 2 4
partition by 分组
order by sa.salary desc 排序
select a.dept_no dept_no, a.emp_no emp_no, a.salary maxSalary from ( select de.dept_no, de.emp_no, sa.salary, rank() over ( partition by de.dept_no order by sa.salary desc ) rank_n from dept_emp de join salaries sa on de.emp_no = sa.emp_no ) a where a.rank_n = 1
where
and
order by
select emp_no, birth_date, first_name, last_name, gender, hire_date from employees where emp_no %2 != 0 and last_name != 'Mary' order by hire_date desc
avg() 函数
内连接
分组
排序
select t.title , avg(s.salary) average from titles t join salaries s on t.emp_no = s.emp_no group by t.title order by average asc
having是在分组后对数据进行过滤 where是在分组前对数据进行过滤
having后面可以使用聚合函数 where后面不可以使用聚合
HAVING SUM(population)>1000000
form -> where -> group by -> having -> select -> order by -> limit
第一种
distinct
select distinct name,id form table
select count(distinct name) form table
第二种
group by
select 重复的字段名 from 表名 group by 重复的字段名
count(*)表示的是直接查询符合条件的数据库表的行数
COUNT(字段)表示的是查询符合条件的列的值不为NULL的行数
count(distinct 字段) 表示的是查询去重之后符合条件的列的值不为NULL的行数
select datediff(day, ‘2008-12-29’, ‘2018-12-30’) as date
select datediff(day,convert(date,‘20220824’,112),convert(date,‘20230824’,112)) from your_table;
case when
select name, case when home = ‘beijing’ then ‘shoudu’ end as shoudu_yes from table
表达式 | 多条件判断 | 适合复杂逻辑
if
SELECT id, name, IF(score >= 60, ‘及格’, ‘不及格’) AS result FROM students;
单条件判断 | 函数形式 | 简单逻辑
笛卡尔积
是两张表的行数的乘积
一般出现在联表查询的时候
内连接可以解决这个问题
窗口函数
除了rank,sql还提供了许多其他窗口函数,用于在指定的范围内进行计算、排序和分析。以下是一些常见的窗口函数。
①dense_mark:分配连续的、不重复的排名给结果集中的行,相同的值会获得相同的排名,而且不会跳过排名。
②row_number:为结果集中的每一行分配唯一的、连续的整数排名,不考虑相同值的行。
③ntile(n):将结果集分成n个大小相等的部分,并为每个部分的行分配一个整数值表示部分号(1到n)。
④lead(column , offset):返回当前行之后的某一行中的列值。
⑤lag(column,offset):返回当前行之前的某一行中的列值。
⑥first_value:获取分组集合中第一行的某个列值。
⑦last_value:获取分组集合中最后一行的某个列值。
⑧sum/avg/min/max(column) over(partition by … order by …):计算指定窗口中某列的总和/平均值/最小/最大值。
①max聚合函数:用于在查询中对某个列的值进行聚合计算,得出整个结果集的最大值。
②max窗口函数:在查询结果集的某个窗口(或分区)上进行计算的函数。窗口函数可以同时获得每个分区的最大值。
mysql 使用format函数
select format(float_column,2) as formatted_float from your_table;
sql server
select round(float_column,2) as formatted_float from your_table;
①inner join返回两个表中的匹配行,如果某行一个表中找不到匹配的行,那么这个行不会在结果中显示。
②left join返回左表中的所有行以及右表中与坐标匹配的行。如果在右表中找不到匹配的行,那么对应的右表列将会显示为NULL。
③right join返回右表的所有行,以及左表中与右表匹配的行。如果在左表中找不到匹配的行,那么对应的左表列将会显示为NULL。
join操作的效率通常比单纯使用子查询的效率要高,但应尽量避免多重嵌套join或join多张表,以免影响查询性能。
mysql
select cast(int_column as char) as string_column from your_table;
在sql中,where子句通常会在窗口函数之前执行。
首先,数据库会根据where子句的条件对表进行筛选,过滤出符合条件的行。然后,在已经筛选出的结果集上,窗口函数开始计算。
这个执行顺序确保了窗口函数在筛选和过滤数据后进行计算,以及在计算窗口函数不会考虑不满足where子句条件的行。
均值使用聚合函数avg计算:
select avg(column) as mean from your_table;
标准差用聚合函数stdev计算:
select stdev(column) as std from your_table;
select convert(varchar(8),date_column,112) from your_table;
select cast(date_column as char(8)) from your_table;