sql查询语句(详细)

本文介绍了SQL的关键字、语法结构,包括选择、过滤、分组、聚合、关联、子查询、时间函数、字符串处理、开窗函数以及基本的增删改操作,旨在帮助读者系统学习和掌握SQL语言。
摘要由CSDN通过智能技术生成

前言

本篇文章为本人在学习sql语句时总结出的学习笔记,本文将我所学习到的sql语句关键字都总结了一下。

总结的来源多种多样,所以每条的书写格式会有写区别

查询语句

select

select 查找的字段 from 表名

select * from 表名 (查找该表所有字段)

select * from 表名 where 条件 (查找符合条件的字段)

例:

select * from students where sex = "男"

where

=等于,<小于,>大于,<=小于等于,>=大于等于,<>或!= 不等于

and和 or或 between…and… 介于两个值之间(包含等于)

in 包含 例:where id in (3,5,9,4,2)

is null 为null

模糊查询(like)

需要配合占位符使用

代表一位字符 李 王__

%代表任意位字符 李%

例:

select * from students where name like  **"李_"**

条件分支

示例语法

CASE WHEN (条件1) THEN 结果1
WHEN (条件2) THEN 结果2       ...
ELSE 其他结果 END

例如

假设有一个学生表 student,包含以下字段:name(姓名)、age(年龄)。请你编写一个 SQL 查询,将学生按照年龄划分为三个年龄等级(age_level):60 岁以上为 “老同学”,20 岁以上(不包括 60 岁以上)为 “年轻”,20 岁及以下、以及没有年龄信息为 “小同学”。

返回结果应包含学生的姓名(name)和年龄等级(age_level),并按姓名升序排序。

SELECT  name,  
   CASE WHEN (age > 60) THEN '老同学'    
   WHEN (age > 20) THEN '年轻'    
   ELSE '小同学'  END AS age_level 
FROM  student 
ORDER BY  name asc

;

时间函数

使用时间函数获取当前日期、当前日期时间和当前时间:

-- 获取当前日期
SELECT DATE() AS current_date;

-- 获取当前日期时间
SELECT DATETIME() AS current_datetime;

-- 获取当前时间
SELECT TIME() AS current_time;

查询结果:

为了方便对比,放到同一个表格

current_datecurrent_datetimecurrent_time
2023-08-012023-08-01 14:30:0014:30:00

字符串处理

1)使用字符串处理函数 UPPER 将姓名转换为大写:

-- 将姓名转换为大写
SELECT name, UPPER(name) AS upper_name
FROM employees;

查询结果:

nameupper_name
小明小明
热dog热DOG
Fish摸摸FISH摸摸
鸡哥鸡哥

2)使用字符串处理函数 LENGTH 计算姓名长度:

-- 计算姓名长度
SELECT name, LENGTH(name) AS name_length
FROM employees;

查询结果:

namename_length
小明2
热dog4
Fish摸摸6
鸡哥2

3)使用字符串处理函数 LOWER 将姓名转换为小写:

-- 将姓名转换为小写并进行条件筛选
SELECT name, LOWER(name) AS lower_name
FROM employees;

查询结果:

namelower_name
小明小明
热dog热dog
Fish摸摸fish摸摸
鸡哥鸡哥

聚合查询

**avg()最大值 **

**count()数量 **

**min()最小值 **

**max()最大值 **

sum()总和

例:select max(age) from student

查表中的年龄最大值

分组查询

group by

例:select max(age) from student group by sex

查表中的男的和女的年龄最大值,两个结果

综合应用:

`select 
   name,sex,sum(sx+yw+yy) 总分,
   (yy+sx+yw)/3 平均分 
from student 
where sex="男" 
group by id order by 总分 desc limit 0,3`

having

分组之后加条件

select 
name,sex,sum(sx+yw+yy) 总分,(yy+sx+yw)/3 平均分 
from student 
where sex="男" 
group by id **having 平均分>60** 
order by 总分 desc limit 0,5

关联查询

inner join

它根据两个表之间的关联条件,将满足条件的行组合在一起。

注意,INNER JOIN 只返回两个表中满足关联条件的交集部分,即在两个表中都存在的匹配行。

假设有一个员工表 employees,包含以下字段:emp_id(员工编号)、emp_name(员工姓名)、department(所属部门)、salary(工资)。数据如下:

emp_idemp_namedepartmentsalary
1小明技术部5000
2鸡哥财务部6000
3李华销售部4500

假设还有一个部门表 departments,包含以下字段:department(部门名称)、manager(部门经理)、location(所在地)。数据如下:

departmentmanagerlocation
技术部张三上海
财务部李四北京
销售部王五广州
摸鱼部赵二吐鲁番

使用 INNER JOIN 进行关联查询,根据员工表和部门表之间的公共字段 部门名称(department) 进行匹配,将员工的姓名、工资以及所属部门和部门经理组合在一起:

SELECT e.emp_name, e.salary, e.department, d.manager
FROM employees e
JOIN departments d ON e.department = d.department;

outer join

它根据指定的关联条件,将两个表中满足条件的行组合在一起,并 包含没有匹配的行

在 OUTER JOIN 中,包括 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 两种类型,它们分别表示查询左表和右表的所有行(即使没有被匹配),再加上满足条件的交集部分。

示例

假设有一个员工表 employees,包含以下字段:emp_id(员工编号)、emp_name(员工姓名)、department(所属部门)、salary(工资)。数据如下:

emp_idemp_namedepartmentsalary
1小明技术部5000
2鸡哥财务部6000
3李华销售部4500

假设还有一个部门表 departments,包含以下字段:department(部门名称)、manager(部门经理)、location(所在地)。数据如下:

departmentmanagerlocation
技术部张三上海
财务部李四北京
人事部王五广州
摸鱼部赵二吐鲁番

使用 LEFT JOIN 进行关联查询,根据员工表和部门表之间的部门名称进行匹配,将员工的姓名、工资以及所属部门和部门经理组合在一起,并包含所有员工的信息:

SELECT e.emp_name, e.salary, e.department, d.manager
FROM employees e
LEFT JOIN departments d ON e.department = d.department;

查询结果:

emp_namesalarydepartmentmanager
小明5000技术部张三
鸡哥6000财务部李四
李华4500销售部NULL

子查询

子查询是指在一个查询语句内部 嵌套 另一个完整的查询语句,内层查询被称为子查询。子查询可以用于获取更复杂的查询结果或者用于过滤数据

假设我们有以下两个数据表:orderscustomers,分别包含订单信息和客户信息。

orders 表:

order_idcustomer_idorder_datetotal_amount
11012023-01-01200
21022023-01-05350
31012023-01-10120
41032023-01-15500

customers 表:

customer_idnamecity
101AliceNew York
102BobLos Angeles
103CharlieChicago

现在,我们希望查询出订单总金额 > 200 的客户的姓名和他们的订单总金额,示例 SQL 如下:

-- 主查询
SELECT name, total_amount
FROM customers
WHERE customer_id IN (
    -- 子查询
    SELECT DISTINCT customer_id
    FROM orders
    WHERE total_amount > 200
);

exists

子查询中的一种特殊类型是 “exists” 子查询,用于检查主查询的结果集是否存在满足条件的记录,它返回布尔值(True 或 False),而不返回实际的数据。

现在,我们希望查询出 存在订单的 客户姓名和订单金额。

使用 exists 子查询的方式,SQL 代码如下:

-- 主查询
SELECT name, total_amount
FROM customers
WHERE EXISTS (
    -- 子查询
    SELECT 1
    FROM orders
    WHERE orders.customer_id = customers.customer_id
);

上述语句中,先遍历客户信息表的每一行,获取到客户编号;然后执行子查询,从订单表中查找该客户编号是否存在,如果存在则返回结果。

查询结果如下:

nametotal_amount
Alice200
Bob350
Charlie500

和 exists 相对的是 not exists,用于查找不满足存在条件的记录。

组合查询

  1. UNION 操作:它用于将两个或多个查询的结果集合并, 并去除重复的行 。即如果两个查询的结果有相同的行,则只保留一行。
  2. UNION ALL 操作:它也用于将两个或多个查询的结果集合并, 但不去除重复的行 。即如果两个查询的结果有相同的行,则全部保留。

假设我们有以下两个数据表:table1table2,分别包含不同部门的员工信息。

table1 表:

emp_idnameagedepartment
101Alice25HR
102Bob28Finance
103Charlie22IT

table2 表:

emp_idnameagedepartment
101Alice25HR
201David27Finance
202Eve24HR
203Frank26IT

现在,我们想要合并这两张表的数据,分别执行 UNION 操作和 UNION ALL 操作。

UNION 操作:

SELECT name, age, department
FROM table1
UNION
SELECT name, age, department
FROM table2;

UNION 操作的结果,去除了重复的行(名称为 Alice):

nameagedepartment
Alice25HR
Bob28Finance
Charlie22IT
David27Finance
Eve24HR
Frank26IT

UNION ALL 操作:

-- UNION ALL操作
SELECT name, age, department
FROM table1
UNION ALL
SELECT name, age, department
FROM table2;

结果如下,保留了重复的行:

nameagedepartment
Alice25HR
Bob28Finance
Charlie22IT
Alice25HR
David27Finance
Eve24HR
Frank26IT

datediff

计算两个数据的差值

例子:力扣197——计算上升的温度

+---------------+---------+ 
| Column Name   | Type    | 
+---------------+---------+ 
| id            | int     | 
| recordDate    | date    | 
| temperature   | int     | 
+---------------+---------+ 
id 是该表具有唯一值的列。 没有具有相同 recordDate 的不同行。 该表包含特定日期的温度信息

编写解决方案,找出与之前(昨天的)日期相比温度更高的所有日期的 id 。

解决:

select w1.id  
from weather w1 join weather w2 on  
datediff(w1.recorddate , w2.recorddate) = 1  
where w1.temperature>w2.temperature;

开窗函数

sum over

在 SQL 中,开窗函数是一种强大的查询工具,它允许我们在查询中进行对分组数据进行计算、 同时保留原始行的详细信息

开窗函数可以与聚合函数(如 SUM、AVG、COUNT 等)结合使用,但与普通聚合函数不同,开窗函数不会导致结果集的行数减少。

打个比方,可以将开窗函数想象成一种 “透视镜”,它能够将我们聚焦在某个特定的分组,同时还能看到整体的全景。

用法:

SUM(计算字段名) OVER (PARTITION BY 分组字段名)
sum over order by

可以实现同组内数据的 累加求和

示例用法如下:

SUM(计算字段名) OVER (PARTITION BY 分组字段名 ORDER BY 排序字段 排序规则)
Rank

Rank 开窗函数是 SQL 中一种用于对查询结果集中的行进行 排名 的开窗函数。它可以根据指定的列或表达式对结果集中的行进行排序,并为每一行分配一个排名。在排名过程中,相同的值将被赋予相同的排名,而不同的值将被赋予不同的排名。

Rank 开窗函数的常见用法是在查询结果中查找前几名(Top N)或排名最高的行。

Rank 开窗函数的语法如下:

RANK() OVER (
  PARTITION BY 列名1, 列名2, ... -- 可选,用于指定分组列
  ORDER BY 列名3 [ASC|DESC], 列名4 [ASC|DESC], ... -- 用于指定排序列及排序方式
) AS rank_column

其中,PARTITION BY 子句可选,用于指定分组列,将结果集按照指定列进行分组;ORDER BY 子句用于指定排序列及排序方式,决定了计算 Rank 时的排序规则。AS rank_column 用于指定生成的 Rank 排名列的别名。

假设我们有订单表 orders,表格数据如下:

order_idcustomer_idorder_datetotal_amount
11012023-01-01200
21022023-01-05350
31012023-01-10120
41032023-01-15500

现在,我们希望为每个客户的订单按照订单金额降序排名,并显示每个订单的详细信息。

SELECT 
    order_id, 
    customer_id, 
    order_date, 
    total_amount,
    RANK() OVER (PARTITION BY customer_id ORDER BY total_amount DESC) AS customer_rank
FROM
    orders;

查询结果:

order_idcustomer_idorder_datetotal_amountcustomer_rank
11012023-01-012001
31012023-01-101202
21022023-01-053501
41032023-01-155001
Row_Number

Row_Number 开窗函数是 SQL 中的一种用于为查询结果集中的每一行 分配唯一连续排名 的开窗函数。

它与之前讲到的 Rank 函数,Row_Number 函数为每一行都分配一个唯一的整数值,不管是否存在并列(相同排序值)的情况。每一行都有一个唯一的行号,从 1 开始连续递增。

Row_Number 开窗函数的语法如下(几乎和 Rank 函数一模一样):

ROW_NUMBER() OVER (
  PARTITION BY column1, column2, ... -- 可选,用于指定分组列
  ORDER BY column3 [ASC|DESC], column4 [ASC|DESC], ... -- 用于指定排序列及排序方式
) AS row_number_column

其中,PARTITION BY子句可选,用于指定分组列,将结果集按照指定列进行分组。ORDER BY 子句用于指定排序列及排序方式,决定了计算 Row_Number 时的排序规则。AS row_number_column 用于指定生成的行号列的别名。

Lag 和 Lead

开窗函数 Lag 和 Lead 的作用是获取在当前行之前或之后的行的值,这两个函数通常在需要比较相邻行数据或进行时间序列分析时非常有用。

1)Lag 函数

Lag 函数用于获取 当前行之前 的某一列的值。它可以帮助我们查看上一行的数据。

Lag 函数的语法如下:

LAG(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY sort_column)

参数解释:

  • column_name:要获取值的列名。
  • offset:表示要向上偏移的行数。例如,offset为1表示获取上一行的值,offset为2表示获取上两行的值,以此类推。
  • default_value:可选参数,用于指定当没有前一行时的默认值。
  • PARTITION BYORDER BY子句可选,用于分组和排序数据。

2)Lead 函数

Lead 函数用于获取 当前行之后 的某一列的值。它可以帮助我们查看下一行的数据。

Lead 函数的语法如下:

LEAD(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY sort_column)

参数解释:

  • column_name:要获取值的列名。
  • offset:表示要向下偏移的行数。例如,offset为1表示获取下一行的值,offset为2表示获取下两行的值,以此类推。
  • default_value:可选参数,用于指定当没有后一行时的默认值。
  • PARTITION BYORDER BY子句可选,用于分组和排序数据。

以下是一个示例,假设我们有一个学生成绩表scores,其中包含学生的成绩和考试日期:

student_idexam_datescore
1012023-01-0185
1012023-01-0578
1012023-01-1092
1012023-01-1580

现在我们想要查询每个学生的考试日期和上一次考试的成绩,以及下一次考试的成绩,示例 SQL 如下:

SELECT 
    student_id,
    exam_date,
    score,
    LAG(score, 1, NULL) OVER (PARTITION BY student_id ORDER BY exam_date) AS previous_score,
    LEAD(score, 1, NULL) OVER (PARTITION BY student_id ORDER BY exam_date) AS next_score
FROM
    scores;

结果将是:

student_idexam_datescoreprevious_scorenext_score
1012023-01-0185NULL78
1012023-01-05788592
1012023-01-10927880
1012023-01-158092NULL

在上面的示例中,我们使用 Lag 函数获取每个学生的上一次考试成绩(previous_score),使用 Lead 函数获取每个学生的下一次考试成绩(next_score)。如果没有上一次或下一次考试,对应的列将显示为 NULL。

增删改

添加:insert

insert into 表名(字段1,字段2,字段3) values(数据1,数据2,数据3)

例:

insert into students (name,sex,age,classid) values("伯元","男",21,1)

删除:delete

delete from 表名 where 条件

例:

delete from students  where calssid = 1

修改:update

update 表名 set 修改的内容 where 条件

例:

update students set sex="女",name="线程",age=12 where id =4
  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值