《MySQL 入门教程》第 22 篇 窗口函数
wptr33 2024-12-01 05:02 21 浏览
文章来源:https://blog.csdn.net/horses/article/details/108226125
原文作者:不剪发的Tony老师
来源平台:CSDN
窗口函数(Window Function)是 MySQL 8.0 新增的一个重要的功能,可以为数据分析提供强大的支持,例如计算分组排名、累积求和、同比/环比增长率等。本篇我们就来了解一下 MySQL 中窗口函数的语法和各种窗口函数的作用。
另外,这里有一份 SQL 窗口函数速查表;欢迎下载保存,以便不时之需。
22.1 窗口函数概述
在第 12 篇中我们学习了常见的聚合函数,包括 AVG、COUNT、MAX、MIN、SUM 以及 GROUP_CONCAT。聚合函数的作用就是对一组数据行进行汇总计算,并且返回单个分析结果。
窗口函数和聚合函数类似之处在于它也是对一组数据进行分析;但是,窗口函数不是将一组数据汇总为单个结果;而是针对查询中的每一行数据,基于和它相关的一组数据计算出一个结果。下图演示了聚合函数和窗口函数的区别:
窗口函数在其他数据库中也叫做分析函数(Analytic Function),或者联机分析处理(OLAP)函数。
为了便于理解,我们可以比较一下聚合函数和窗口函数的结果。以下示例分别将 COUNT 作为聚合函数和窗口函数,计算员工的人数:
SELECT count(*)
FROM employee;
count(*)|
--------|
25|
SELECT emp_id, emp_name, count(*) OVER ()
FROM employee;
emp_id|emp_name |count(*) OVER ()|
------|---------|----------------|
13|关兴 | 25|
11|关平 | 25|
2|关羽 | 25|
1|刘备 | 25|
16|周仓 | 25|
8|孙丫鬟 | 25|
...
聚合函数(COUNT(*))通常也可以作为窗口函数(COUNT(*) OVER()),区别在于后者包含了OVER关键字;空括号表示将所有数据作为整体进行分析,所以得到的数值和聚合函数一样。查询结果中,聚合函数只返回了一个汇总结果,而窗口函数为每一个员工都返回了一个结果。
22.2 窗口函数的定义
窗口函数与其他函数的语法区别主要在于OVER子句,接下来我们介绍它的语法。窗口函数的定义如下:
window_function ( expr ) OVER (
PARTITION BY ...
ORDER BY ...
frame_clause
)
其中,window_function 是窗口函数的名称;expr 是参数,有些函数不需要参数;OVER子句包含三个选项:分区(PARTITION BY)、排序(ORDER BY)以及窗口大小(frame_clause)。
22.2.1 分区选项(PARTITION BY)
PARTITION BY选项用于将数据行拆分成多个分区(组),窗口函数基于每一行数据所在的组进行计算并返回结果,它的作用类似于GROUP BY分组。如果省略了 PARTITION BY,所有的数据作为一个组进行计算,上文中的示例就是如此。
以下示例按照不同的部门分别统计员工的月薪合计:
SELECT emp_name "姓名", salary "月薪", dept_id "部门编号",
sum(salary) OVER (PARTITION BY dept_id) AS "部门月薪合计"
FROM employee;
其中,OVER 子句中的 PARTITION BY 选项表示按照部门进行分区;因此,SUM 函数按照部门分别统计月薪的合计值。该语句的结果如下(只显示了前 3 个部门的结果):
前 3 行数据的部门编号都为 1,因此该部门的月薪合计为 30000 + 26000 + 24000 = 80000;其他部门的数据也采用同样的方式进行计算。
SQL 标准要求 PARTITION BY 之后只能使用字段名,不过 MySQL 允许指定表达式。另外,我们也可以在 PARTITION BY 之后指定多个分组字段,例如同时按照部门和性别进行分组分析。
22.2.2 排序选项(ORDER BY)
OVER 子句中的ORDER BY选项用于指定分区内的排序方式,与 ORDER BY 子句的作用类似,通常用于数据的排名分析。以下示例用于计算每个员工在部门内的月薪排名:
SELECT emp_name "姓名", salary "月薪", dept_id "部门编号",
rank() OVER (
PARTITION BY dept_id
ORDER BY salary DESC
) AS "部门排名"
FROM employee;
其中,PARTITION BY 选项表示按照部门进行分区;ORDER BY 选项指定在分区内按照月薪从高到低进行排序;RANK 函数用于计算名次,该函数将会在下文中进行介绍。
该语句的结果如下(只显示了前 3 个部门的结果):
前 3 行数据的部门编号都为 1;“刘备”的月薪最高,在部门内排名第一;“关羽”排名第二;“张飞”排名第三。其他部门的数据采用同样的方式进行计算。
ORDER BY 选项用于指定分区内数据的排序,排序字段数据相同的行是对等行(peer)。如果省略 ORDER BY ,分区内的数据不进行排序,不按照固定顺序处理, 而且所有数据都是对等行。
22.2.3 窗口选项(frame_clause)
frame_clause选项用于在当前分区内指定一个计算窗口,也就是一个与当前行相关的数据子集。指定了窗口之后,分析函数不再基于分区进行计算,而是基于窗口内的数据进行计算。窗口会随着当前处理的数据行而移动,例如:
- 定义一个从分区开始到当前数据行结束的窗口,可以计算截止到每一行的累计总值。
- 定义一个从当前行之前 N 行数据到当前行之后 N 行数据的窗口,可以计算移动平均值。
具体来说,窗口大小的常用选项如下:
{ ROWS | RANGE } frame_start
{ ROWS | RANGE } BETWEEN frame_start AND frame_end
其中,ROWS表示以行为单位指定窗口的偏移量,RANGE表示以数值(例如 30 分钟)为单位指定窗口的偏移量。frame_start 和 frame_end 分别表示窗口的开始行和结束行,它们的可能取值如下:
CURRENT ROW
UNBOUNDED PRECEDING
UNBOUNDED FOLLOWING
expr PRECEDING
expr FOLLOWING
frame_start 和 frame_end 的具体意义如下:
- CURRENT ROW:对于 ROWS 方式,代表了当前行;对于 RANGE,代表了当前行的所有对等行。
- UNBOUNDED PRECEDING:代表了分区中的第一行。
- UNBOUNDED FOLLOWING:代表了分区中的最后一行。
- expr PRECEDING:对于 ROWS 方式,代表了当前行之前的第 expr 行;对于 RANGE,代表了等于当前行的值减去 expr 的所有行;如果当前行的值为 NULL,代表了当前行的所有对等行。
- expr FOLLOWING:对于 ROWS 方式,代表了当前行之后的第 expr 行;对于 RANGE,代表了等于当前行的值加上 expr 的所有行;如果当前行的值为 NULL,代表了当前行的所有对等行。
如果只有 frame_start,默认以当前行作为窗口的结束。如果同时指定了两者,frame_start 不能晚于 frame_end,例如 BETWEEN 1 FOLLOWING AND 1 PRECEDING 就是一个无效的窗口。下图可以方便我们理解这些选项的含义:
CURRENT ROW表示当前正在处理的行;其他的行可以使用相对当前行的位置表示。需要注意,窗口的大小不会超出当前分区的范围。
以下示例按照部门统计员工的累计月薪值:
SELECT d.dept_name "部门名称", e.emp_name "姓名", e.salary "月薪",
sum(salary) OVER (
PARTITION BY e.dept_id
ORDER BY e.emp_id
ROWS UNBOUNDED PRECEDING
) AS "部门累计月薪"
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id);
其中,PARTITION BY 选项表示按照部门进行分区;ORDER BY 选项表示按照工号进行排序;窗口子句 ROWS UNBOUNDED PRECEDING 指定窗口从分区的第一行开始,默认到当前行结束;因此 SUM 函数计算的是部门内累计到当前员工为止的月薪合计。该查询的结果如下(只显示了前 3 个部门的结果):
对于“行政管理部”,第一个员工的月薪为 30000,累计也是 30000;第二个员工的月薪为 26000,累计为 30000 + 26000 = 56000;依此类推,直到统计完该部门的所有员工;然后开始统计下一个部门的数据。
22.2.4 命名窗口
窗口函数的 OVER 子句除了直接定义三种选项之外,还可以使用一个预定义的窗口变量进行定义。窗口变量使用WINDOW子句进行定义,语法位于 HAVING 和 ORDER BY 之间。
window_function(expr) OVER window_name
WINDOW window_name AS (PARTITION BY ... ORDER BY ... frame_clause)
WINDOW window_name AS (other_window_name)
如果查询中多个窗口函数的 OVER 子句相同,利用 WINDOW 子句定义一个窗口变量,然后在多个 OVER 子句中使用该变量可以简化查询语句。例如:
SELECT d.dept_name "部门名称", e.emp_name "姓名", e.salary "月薪",
sum(salary) OVER w AS "部门累计月薪",
count(*) OVER w AS "部门累计人数"
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id)
WINDOW w AS (
PARTITION BY e.dept_id
ORDER BY e.emp_id
ROWS UNBOUNDED PRECEDING
);
接下来我们介绍一些常见的窗口函数和示例。
22.3 常用窗口函数
常见的窗口函数可以分为以下几类:聚合窗口函数、排名窗口函数以及取值窗口函数。
窗口函数只能出现在 SELECT 列表和 ORDER BY 子句中,查询语句的处理顺序依次为 FROM、WHERE、GROUP BY、聚合函数、HAVING、窗口函数、SELECT DISTINCT、ORDER BY、LIMIT。
22.3.1 聚合窗口函数
常用的聚合函数,例如 AVG、SUM、COUNT 等,也可以作为窗口函数使用。上文我们已经列举了一些聚合窗口函数的示例,再来看一个使用 AVG 函数计算移动平均值的例子:
SELECT d.dept_name "部门名称", e.emp_name "姓名", e.salary "月薪",
avg(salary) OVER (
PARTITION BY e.dept_id
ORDER BY e.salary
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
) AS "移动平均月薪"
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id);
部门名称 |姓名 |月薪 |移动平均月薪 |
--------|------|--------|------------|
行政管理部|张飞 |24000.00|25000.000000|
行政管理部|关羽 |26000.00|26666.666667|
行政管理部|刘备 |30000.00|28000.000000|
人力资源部|魏延 | 8000.00| 8250.000000|
人力资源部|黄忠 | 8500.00|13833.333333|
人力资源部|诸葛亮|25000.00|16750.000000|
...
其中,PARTITION BY 选项表示按照部门进行分区;ORDER BY 选项表示按照月薪从低到高进行排序;窗口子句 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 指定窗口从当前行的前一行开始,到当前行的下一行结束;因此该函数计算的是每个部门内员工与其前后各一个员工的平均月薪值。
移动平均值通常用于处理时间序列的数据。例如,厂房的温度检测器获取了每秒钟的温度,我们可以使用以下窗口计算前五分钟内的平均温度:
avg(temperature) OVER (ORDER BY ts RANGE BETWEEN interval '5 minute' PRECEDING AND CURRENT ROW)
22.3.2 排名窗口函数
排名窗口函数用于对数据进行分组排名。常见的排名窗口函数包括:
- ROW_NUMBER,为分区中的每行数据分配一个序列号,序列号从 1 开始分配。
- RANK,计算每行数据在其分区中的名次;如果存在名次相同的数据,后续的排名将会产生跳跃。
- DENSE_RANK,计算每行数据在其分区中的名次;即使存在名次相同的数据,后续的排名也是连续的值。
- PERCENT_RANK,以百分比的形式显示每行数据在其分区中的名次;如果存在名次相同的数据,后续的排名将会产生跳跃。
- CUME_DIST,计算每行数据在其分区内的累积分布,也就是该行数据及其之前的数据的比率;取值范围大于 0 并且小于等于 1。
- NTILE,将分区内的数据分为 N 等份,为每行数据计算其所在的位置。
排名窗口函数不支持动态的窗口大小(frame_clause),而是以当前分区作为分析的窗口。以下示例按照部门分组,并计算每个员工在其部门中的月薪排名,分别使用了 4 个不同的排名函数:
SELECT d.dept_name "部门名称", e.emp_name "姓名", e.salary "月薪",
ROW_NUMBER() OVER (PARTITION BY e.dept_id ORDER BY e.salary DESC) AS "row_number",
RANK() OVER (PARTITION BY e.dept_id ORDER BY e.salary DESC) AS "rank",
DENSE_RANK() OVER (PARTITION BY e.dept_id ORDER BY e.salary DESC) AS "dense_rank",
PERCENT_RANK() OVER (PARTITION BY e.dept_id ORDER BY e.salary DESC) AS "percent_rank"
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id);
部门名称 |姓名 |月薪 |row_number|rank|dense_rank|percent_rank |
--------|-----|--------|----------|----|----------|-------------------|
行政管理部|刘备 |30000.00| 1| 1| 1| 0.0|
行政管理部|关羽 |26000.00| 2| 2| 2| 0.5|
行政管理部|张飞 |24000.00| 3| 3| 3| 1.0|
...
研发部 |赵云 |15000.00| 1| 1| 1| 0.0|
研发部 |周仓 | 8000.00| 2| 2| 2| 0.125|
研发部 |关兴 | 7000.00| 3| 3| 3| 0.25|
研发部 |关平 | 6800.00| 4| 4| 4| 0.375|
研发部 |赵氏 | 6600.00| 5| 5| 5| 0.5|
研发部 |廖化 | 6500.00| 6| 6| 6| 0.625|
研发部 |张苞 | 6500.00| 7| 6| 6| 0.625|
研发部 |赵统 | 6000.00| 8| 8| 7| 0.875|
研发部 |马岱 | 5800.00| 9| 9| 8| 1.0|
...
其中,4 个函数的 OVER 子句完全相同;PARTITION BY 表示按照部门进行分区;ORDER BY 表示按照月薪从高到低进行排序。我们以结果中的“研发部”为例进行分析:
- ROW_NUMBER 函数为每个员工分配了一个连续的数字编号,可以看作是一种排名。其中“廖化”和“张苞”的月薪相同,但是编号不同;
- RANK 函数为每个员工指定了一个名次,其中“廖化”和“张苞”的名次都是 6。在他们之后的“赵统”的名次为 8,产生了跳跃;
- DENSE_RANK 函数为每个员工指定了一个名次,其中“廖化”和“张苞”的名次都是 6。在他们之后的“赵统”的名次为 7,名次是连续值;
- PERCENT_RANK 函数按照百分比指定名次,取值位于 0 到 1 之间。其中“赵统”的百分比排名为 0.875,也产生了跳跃。
以下语句演示了 CUME_DIST 和 NTILE 函数的作用:
SELECT emp_name AS "姓名", salary AS "月薪",
CUME_DIST() OVER (ORDER BY salary DESC) AS "累积占比",
NTILE(5) OVER (ORDER BY salary DESC) AS "相对位置"
FROM employee;
姓名 |月薪 |累积占比|相对位置|
-----|--------|------|----|
刘备 |30000.00| 0.04| 1|
关羽 |26000.00| 0.08| 1|
诸葛亮|25000.00| 0.12| 1|
张飞 |24000.00| 0.16| 1|
赵云 |15000.00| 0.2| 1|
孙尚香|12000.00| 0.24| 2|
...
糜竺 | 4300.00| 0.84| 5|
黄权 | 4200.00| 0.88| 5|
庞统 | 4100.00| 0.92| 5|
蒋琬 | 4000.00| 1.0| 5|
邓芝 | 4000.00| 1.0| 5|
其中,OVER 子句没有指定分区选项,因此所有的员工作为一个整体进行分析;ORDER BY 按照月薪从高到低进行排序。从结果可以看出,20% 的员工月薪大于等于 15000;或者说,月薪 15000 意味着在公司中的排名属于最高的 20%。NTILE 将员工按照月薪从高到低分成了 5 个组,相对位置为 1 的员工是月薪最高的 20% 员工。
22.3.3 取值窗口函数
取值窗口函数用于返回指定位置上的数据。常见的取值窗口函数包括:
- FIRST_VALUE,返回窗口内第一行的数据。
- LAST_VALUE,返回窗口内最后一行的数据。
- NTH_VALUE,返回窗口内第 N 行的数据。
- LAG,返回分区中当前行之前的第 N 行的数据。
- LEAD,返回分区中当前行之后第 N 行的数据。
其中,LAG 和 LEAD 函数不支持动态的窗口大小(frame_clause),而是以当前分区作为分析的窗口。
以下语句使用 FIRST_VALUE、LAST_VALUE 以及 NTH 函数分别获取每个部门内部月薪最高、月薪最低以及月薪第二高的员工:
SELECT d.dept_name "部门名称", e.emp_name "姓名", e.salary "月薪",
first_value(salary) OVER w "最高月薪",
last_value(salary) OVER w "最低月薪",
nth_value(salary, 2) OVER w "第二高月薪"
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id)
WINDOW w AS (
PARTITION BY e.dept_id
ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER BY e.dept_id, salary DESC;
部门名称 |姓名 |月薪 |最高月薪 |最低月薪 |第二高月薪|
--------|-----|--------|--------|--------|--------|
行政管理部|刘备 |30000.00|30000.00|24000.00|26000.00|
行政管理部|关羽 |26000.00|30000.00|24000.00|26000.00|
行政管理部|张飞 |24000.00|30000.00|24000.00|26000.00|
人力资源部|诸葛亮|25000.00|25000.00| 8000.00| 8500.00|
人力资源部|黄忠 | 8500.00|25000.00| 8000.00| 8500.00|
人力资源部|魏延 | 8000.00|25000.00| 8000.00| 8500.00|
...
以上三个函数的默认窗口是从当前分区的第一行到当前行,所以我们在OVER子句中将窗口设置为整个分区。
LAG 和 LEAD 函数可以用于计算销量数据的环比/同比增长。我们创建一个新的数据表:sales_monthly,它记录了不同产品按月统计的销售金额。以下语句统计不同产品每个月的环比增长率:
SELECT product AS "产品", ym "年月", amount "销量",
(amount - LAG(amount, 1) OVER (PARTITION BY product ORDER BY ym))/
LAG(amount, 1) OVER (PARTITION BY product ORDER BY ym) * 100 AS "环比增长率(%)"
FROM sales_monthly
ORDER BY product, ym;
产品|年月 |销量 |环比增长率(%)|
---|------|--------|---------|
桔子|201801|10154.00| |
桔子|201802|10183.00| 0.285602|
桔子|201803|10245.00| 0.608858|
桔子|201804|10325.00| 0.780869|
桔子|201805|10465.00| 1.355932|
桔子|201806|10505.00| 0.382226|
桔子|201807|10578.00| 0.694907|
桔子|201808|10680.00| 0.964265|
桔子|201809|10788.00| 1.011236|
桔子|201810|10838.00| 0.463478|
桔子|201811|10942.00| 0.959587|
桔子|201812|10988.00| 0.420398|
桔子|201901|11099.00| 1.010193|
桔子|201902|11181.00| 0.738805|
桔子|201903|11302.00| 1.082193|
桔子|201904|11327.00| 0.221200|
桔子|201905|11423.00| 0.847532|
桔子|201906|11524.00| 0.884181|
...
其中,LAG(amount, 1) 表示获取上一期的销量;PARTITION BY 表示按照产品分区;ORDER BY 表示按照月份进行排序;当前月份的销量减去上个月的销量,再除以上个月的销量,就是环比增长率。
想一想,怎么计算同比增长率呢?同比增长是指本期数据与上一年度或历史同期相比的增长。例如,2019 年 6 月的销量与 2018 年 6 月的销量相比增加的部分。
对了,在这里说一下,我目前是在职Java开发,如果你现在正在学习Java,了解Java,渴望成为一名合格的Java开发工程师,在入门学习Java的过程当中缺乏基础入门的视频教程,可以关注并私信我:01。获取。我这里有最新的Java基础全套视频教程。
- 上一篇:MySQL常用函数,程序员真得看看
- 下一篇:Mysql单行函数
相关推荐
- Python自动化脚本应用与示例(python办公自动化脚本)
-
Python是编写自动化脚本的绝佳选择,因其语法简洁、库丰富且跨平台兼容性强。以下是Python自动化脚本的常见应用场景及示例,帮助你快速上手:一、常见自动化场景文件与目录操作...
- Python文件操作常用库高级应用教程
-
本文是在前面《Python文件操作常用库使用教程》的基础上,进一步学习Python文件操作库的高级应用。一、高级文件系统监控1.1watchdog库-实时文件系统监控安装与基本使用:...
- Python办公自动化系列篇之六:文件系统与操作系统任务
-
作为高效办公自动化领域的主流编程语言,Python凭借其优雅的语法结构、完善的技术生态及成熟的第三方工具库集合,已成为企业数字化转型过程中提升运营效率的理想选择。该语言在结构化数据处理、自动化文档生成...
- 14《Python 办公自动化教程》os 模块操作文件与文件夹
-
在日常工作中,我们经常会和文件、文件夹打交道,比如将服务器上指定目录下文件进行归档,或将爬虫爬取的数据根据时间创建对应的文件夹/文件,如果这些还依靠手动来进行操作,无疑是费时费力的,这时候Pyt...
- python中os模块详解(python os.path模块)
-
os模块是Python标准库中的一个模块,它提供了与操作系统交互的方法。使用os模块可以方便地执行许多常见的系统任务,如文件和目录操作、进程管理、环境变量管理等。下面是os模块中一些常用的函数和方法:...
- 21-Python-文件操作(python文件的操作步骤)
-
在Python中,文件操作是非常重要的一部分,它允许我们读取、写入和修改文件。下面将详细讲解Python文件操作的各个方面,并给出相应的示例。1-打开文件...
- 轻松玩转Python文件操作:移动、删除
-
哈喽,大家好,我是木头左!Python文件操作基础在处理计算机文件时,经常需要执行如移动和删除等基本操作。Python提供了一些内置的库来帮助完成这些任务,其中最常用的就是os模块和shutil模块。...
- Python 初学者练习:删除文件和文件夹
-
在本教程中,你将学习如何在Python中删除文件和文件夹。使用os.remove()函数删除文件...
- 引人遐想,用 Python 获取你想要的“某个人”摄像头照片
-
仅用来学习,希望给你们有提供到学习上的作用。1.安装库需要安装python3.5以上版本,在官网下载即可。然后安装库opencv-python,安装方式为打开终端输入命令行。...
- Python如何使用临时文件和目录(python目录下文件)
-
在某些项目中,有时候会有大量的临时数据,比如各种日志,这时候我们要做数据分析,并把最后的结果储存起来,这些大量的临时数据如果常驻内存,将消耗大量内存资源,我们可以使用临时文件,存储这些临时数据。使用标...
- Linux 下海量文件删除方法效率对比,最慢的竟然是 rm
-
Linux下海量文件删除方法效率对比,本次参赛选手一共6位,分别是:rm、find、findwithdelete、rsync、Python、Perl.首先建立50万个文件$testfor...
- Python 开发工程师必会的 5 个系统命令操作库
-
当我们需要编写自动化脚本、部署工具、监控程序时,熟练操作系统命令几乎是必备技能。今天就来聊聊我在实际项目中高频使用的5个系统命令操作库,这些可都是能让你效率翻倍的"瑞士军刀"。一...
- Python常用文件操作库使用详解(python文件操作选项)
-
Python生态系统提供了丰富的文件操作库,可以处理各种复杂的文件操作需求。本教程将介绍Python中最常用的文件操作库及其实际应用。一、标准库核心模块1.1os模块-操作系统接口主要功能...
- 11. 文件与IO操作(文件io和网络io)
-
本章深入探讨Go语言文件处理与IO操作的核心技术,结合高性能实践与安全规范,提供企业级解决方案。11.1文件读写11.1.1基础操作...
- Python os模块的20个应用实例(python中 import os模块用法)
-
在Python中,...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)