MySQL——2、SQL基础

一、导入示例数据库。
第一篇文章我是在mysql的命令行里导入的数据库。
参考教程 https://www.yiibai.com/mysql/how-to-load-sample-database-into-mysql-database-server.html
二、SQL和MYSQL区别
SQL是结构化查询语言(Structured Query Language)。
MYSQL是一个关系型数据库管理系统。
两者的关系:MYSQL是一种关系数据库,SQL则是操作这种关系数据库的的编程语言。
三、SQL数据类型
在这里插入图片描述
四、定义命令(DDL)
一 建库

1.create database 数据库名;

2.drop database 数据库名;

命名库名和表名,一般以字母开头,可以包括字母/数字/下划线。

二 建表

1.create table 表名(列名 类型,~~~~~~~~~~~~);

2.drop table 表名;

数据表命名规则:以姓名缩写开头,中间反应表内容,最后以日期结束。
创建表加入约束:
常见的约束:

1)非空约束,not null,针对某个字段设置其值不为空,如学生姓名不为空.
2)唯一约束,unique,它可以使某个字段的值不能重复.
3)主键约束,primary key,主键可以标识记录的唯一性.

三 查库查表

1.show databases;

2.use 库名;

3.show tables;

4.desc 表名;(看字段及类型)

四 增.删.改.更新已有表

Alter table语句用于在已有表中添加,修改或删除列,更新表名,字段类型。

1.增加一列

Alter table 表名 add 列名 新列数据类型;

2.删除一列

Alter table 表名 drop 列名;

3.修改字段名

Alter table 表名 change 旧字段名 新字段名 类型;

4.修改表名

Alter table 旧表名 rename 新表名;
五、操作命令
往往针对行,不是列。

1.insert into 表名(列名)values(各列值);

1.若字符型的,需要用单引号。

2.指定列名时,列的顺序与原表不一致也可,没指定列名时,列的顺序与原表默认一致。

2.dalete from 表名(where列名称=值)

3.upset 表名 set 列名=新值 (where 条件)

不限制where,则更新一列。

upset hy_order_20170410 set order_money=133 where member_id=233;
六、查询命令
1.select 列名 from 表A

1.查询指定要显示的字段。若要查看所有的列,则用*

2.distinct知识点:

为了查询结果不重复;

用在select后;

select distinct member_id from db_order_20170411;

可以对多个字段进行去重(多个字段均相同才会去重);

2.where 查询条件

针对行的各种过滤操作。若过滤的是文本型的,需要单引号。

1.比较:<,>,=,<=,>=,<>

2.指定范围:between and/not between and

3.集合:in,not in

4.空值判断:not null ,null 

5.And ,Or

查询条件之模糊查询like

1.%:表示任意长度的字符串,长度可为0。

    like 'a%b',表示以a开头,以b结尾任意长度的内容。

2._:一个下划线就表示一个字符。

like 'a_b',以a开头,以b结尾任意长度为3个字符的内容。

例子:查询订单ID中尾号为5的所有订单。

select *from db_order_2017411

where id like ‘%5’;

3.Group by 列名

按指定列名进行分组统计。

对select后面的字段进行汇总。

Group by一定是跟着汇总函数一起使用的。

group by 后面的字段:select后汇总函数前的所有字段都可以作为group by 后面的字段。

汇总函数:

1.sum()

2.min()

3.max()

4.count()  里面可以涉及去重count(distinct l列名)  看到计数,要先去重,再计数。

5.avg()

例子:把订单金额从顾客和订单状态两个维度拆分查询。

select memeber_id
       ,status
       ,sum(order_money) as sum_money
from db_order.hy_order_20170411
group by memben_id ,status
order by memben_id;

4.Having 列名

对分组统计后的结果进行过滤。若不是对统计汇总后的结果过滤,我们用的是where。

一定是和group by 一起使用。

例子:统计每个会员累计购买金额,且要求累计购买大于100

select member_id
      ,sum(order_money) as sum_money

from db_demo.hy_order_20170411

group by member_id

having sum_money >100

order by sum_money desc;
(这个涉及两个逻辑:先统计出来每个会员累计购买金额,再对累计购买金额大于100的过滤。要思考过滤是对统计前还是统计后)

区分:

1.先对会员的订单金额累计汇总后,只取大于100的记录。这个过滤用having.

2.要统计的是订单金额大于100的会员记录,这个用where过滤。

5.order by 列名

对查询结果进行排序(ascending 升序,desc 降序,默认是升序)

6.limit N;
七、SQL函数
一.主要函数类型

时间函数(常用)

文本函数(也叫字符函数)

数学函数

控制函数(常用)

二.时间函数

2.1

DATE_FORMAT() ——函数用于以不同的格式显示日期 / 时间数据。

DATE_FORMAT(date,format)

date 参数是合法的日期或者时间或者日期时间;format 规定日期/时间的输出格式(年月日看需求想要哪个)。
在这里插入图片描述

对于一张表中的日期和时间的字段,我们可能有这样的需求,按某个时间参数来统计比如:按年统计,按周统计,按天统计,按每小时统计,都用这个函数。

2.2常用时间函数
在这里插入图片描述

2.3常用时间加减函数
在这里插入图片描述

要注意:一个日期原本可能是文本型的(在字段的左上小标可以看的出来),要转化成日期时间的format型。

例如:

select create_time
      ,date_add(create_time,interval,7 day) as day_7
      ,date_add(create_time,interval,-3 hour) as day_-3
from db_demo.hy_order_20170411;

三.文本函数

在这里插入图片描述

concat()拼接函数经常用在百分比。
例如:

select id
      ,substring(id,2,3) as id_3
from db_order.hy_order_20170411;

例如:

select concat(10.0/30*100,'%');

四.数学函数

在这里插入图片描述

例如:

如果订单金额大于等于50就满足了抽奖条件,随机抽取2名作为得奖者,用随机函数构建得奖名单。

select id

       ,member_id

       ,order_money

       ,rand() as flag

from db_demo.hy_order_20170411

where order_money>=50

order by rand() desc;

五.控制函数

控制函数主要两类函数。case when或if

5.1 case when——如果满足某些条件,则进行什么的统计/赋值操作,生成相应的结果;

Case when 条件 then 结果

      when  条件 then 结果

      when  条件 then 结果

else 结果

end as 列名;

注意:case开始end结束;else不是必须的。
select case when order money <=50 then '低'

                   when order money>50 and order money<=100 then '中'

                   when order money >100 then '高'

            end as c_type

              ,sum(order money) as sum_money

              ,count(distinct member_id) as member_number

from db_demo.hy_order_20170411

where order money is not null

group by case when order money <=50 then '低'

                       when order money>50 and order money<=100 then '中'

                       when order money >100 then '高'

                 end

5.2 if——如果某个条件成立,则选择第二个参数,否则选择第三个参数。

IF(条件,参数1,参数2)

用if的嵌套才能实现上述case when的结果

例如:

select id

       ,order money

       ,if(order money >100,if(when order money>50 and order money<=100,‘中’,‘高’),‘低’) as c_type

from db_demo.hy_order_20170411;

  • 小实战1:
    题目:查找重复的电子邮箱(难度:简单)
    创建 email表,并插入如下三行数据
    ±—±--------+
    | Id | c |
    ±—±--------+
    | 1 | [email protected] |
    | 2 | [email protected] |
    | 3 | [email protected] |
    ±—±--------+
    题目要求:编写一个 SQL 查询,查找 Email 表中所有重复的电子邮箱。
    根据以上输入,你的查询应返回以下结果:
    ±--------+
    | Email |
    ±--------+
    | [email protected] |
    ±--------+
    说明:所有电子邮箱都是小写字母。
    答案:在这里插入图片描述
    在这里插入图片描述
    实现结果:
    在这里插入图片描述
  • 小实战2
    题目:查找大国(难度:简单)
    创建如下 World 表
    ±----------------±-----------±-----------±-------------±--------------+
    | name | continent | area | population | gdp |
    ±----------------±-----------±-----------±-------------±--------------+
    | Afghanistan | Asia | 652230 | 25500100 | 20343000 |
    | Albania | Europe | 28748 | 2831741 | 12960000 |
    | Algeria | Africa | 2381741 | 37100000 | 188681000 |
    | Andorra | Europe | 468 | 78115 | 3712000 |
    | Angola | Africa | 1246700 | 20609294 | 100990000 |
    ±----------------±-----------±-----------±-------------±--------------+
    如果一个国家的面积超过300万平方公里,或者(人口超过2500万并且gdp超过2000万),那么这
    题目要求:编写一个SQL查询,输出表中所有大国家的名称、人口和面积。
    例如,根据上表,我们应该输出:
    ±-------------±------------±-------------+
    | name | population | area |
    ±-------------±------------±-------------+
    | Afghanistan | 25500100 | 652230 |
    | Algeria | 37100000 | 2381741 |
    ±-------------±------------±-------------+
    答案:
CREATE TABLE World (
name VARCHAR(50) NOT NULL,
continent VARCHAR(50) NOT NULL,
area INT NOT NULL,
population INT NOT NULL,
gdp INT NOT NULL
);
INSERT INTO World
  VALUES('Afghanistan','Asia',652230,25500100,20343000);
INSERT INTO World 
  VALUES('Albania','Europe',28748,2831741,12960000);
INSERT INTO World 
  VALUES('Algeria','Africa',2381741,37100000,188681000);
INSERT INTO World
  VALUES('Andorra','Europe',468,78115,3712000);
INSERT INTO World
  VALUES('Angola','Africa',1246700,20609294,100990000);
SELECT
	`name`,
	population,
	area 
FROM
	World 
WHERE
	area > 3000000 
	OR ( population > 25000000 AND gdp > 20000000 );

实现结果:
在这里插入图片描述

  • 小实战3
    题目:超过5名学生的课(难度:简单)
    创建如下所示的courses 表 ,有: student (学生) 和 class (课程)。
    例如,表:
    ±--------±-----------+
    | student | class |
    ±--------±-----------+‘’
    | A | Math |
    | B | English |
    | C | Math |
    | D | Biology |
    | E | Math |
    | F | Computer |
    | G | Math |
    | H | Math |
    | I | Math |
    | A | Math |
    ±--------±-----------+

编写一个 SQL 查询,列出所有超过或等于5名学生的课。
应该输出:
±--------+
| class |
±--------+
| Math |
±--------+
Note:
学生在每个课中不应被重复计算。
答案:
在这里插入图片描述
结果:
在这里插入图片描述

  • 小实战4
    交换工资(难度:简单)
    创建一个 salary表,如下所示,有m=男性 和 f=女性的值 。
    例如:
    | id | name | sex | salary |
    |----|------|-----|--------|
    | 1 | A | m | 2500 |
    | 2 | B | f | 1500 |
    | 3 | C | m | 5500 |
    | 4 | D | f | 500 |

交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求使用一个更新查询,并且没有中间临时表。
运行你所编写的查询语句之后,将会得到以下表:

id name sex salary
1 A f 2500
2 B m 1500
3 C f 5500
4 D m 500

答案:
在这里插入图片描述
结果:
在这里插入图片描述

  • 小实战5
    题目:组合两张表 (难度:简单)
    在数据库中创建表1和表2,并各插入三行数据(自己造)
    表1: Person
    ±------------±--------+
    | 列名 | 类型 |
    ±------------±--------+
    | PersonId | int |
    | FirstName | varchar |
    | LastName | varchar |
    ±------------±--------+
    PersonId 是上表主键

表2: Address
±------------±--------+
| 列名 | 类型 |
±------------±--------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
±------------±--------+
AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:FirstName, LastName, City, State
答案:
在这里插入图片描述
结果:
在这里插入图片描述

  • 小实战6
    题目:删除重复的邮箱(难度:简单)
    编写一个 SQL 查询,来删除 email 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。
    ±—±--------+
    | Id | Email |
    ±—±--------+
    | 1 | [email protected] |
    | 2 | [email protected] |
    | 3 | [email protected] |
    ±—±--------+
    Id 是这个表的主键。
    例如,在运行你的查询语句之后,上面的 Person表应返回以下几行:
    ±—±-----------------+
    | Id | Email |
    ±—±-----------------+
    | 1 | [email protected] |
    | 2 | [email protected] |
    ±—±-----------------+
    答案:
    逻辑:分组取最小值。
    在这里插入图片描述
  • 小实战7
    题目:各部门工资最高的员工(难度:中等)
    创建Employee 表,包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。
    ±—±------±-------±-------------+
    | Id | Name | Salary | DepartmentId |
    ±—±------±-------±-------------+
    | 1 | Joe | 70000 | 1 |
    | 2 | Henry | 80000 | 2 |
    | 3 | Sam | 60000 | 2 |
    | 4 | Max | 90000 | 1 |
    ±—±------±-------±-------------+
    创建Department 表,包含公司所有部门的信息。
    ±—±---------+
    | Id | Name |
    ±—±---------+
    | 1 | IT |
    | 2 | Sales |
    ±—±---------+
    编写一个 SQL 查询,找出每个部门工资最高的员工。例如,根据上述给定的表格,Max 在 IT 部门有最高工资,Henry 在 Sales 部门有最高工资。
    ±-----------±---------±-------+
    | Department | Employee | Salary |
    ±-----------±---------±-------+
    | IT | Max | 90000 |
    | Sales | Henry | 80000 |
    ±-----------±---------±-------+
    答案+结果:
    在这里插入图片描述
  • 小实战8
    题目:换座位(难度:中等)
    小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。
    其中纵列的 id 是连续递增的
    小美想改变相邻俩学生的座位。
    你能不能帮她写一个 SQL query 来输出小美想要的结果呢?
    请创建如下所示seat表:
    示例:
    ±--------±--------+
    | id | student |
    ±--------±--------+
    | 1 | Abbot |
    | 2 | Doris |
    | 3 | Emerson |
    | 4 | Green |
    | 5 | Jeames |
    ±--------±--------+
    假如数据输入的是上表,则输出结果如下:
    ±--------±--------+
    | id | student |
    ±--------±--------+8
    | 1 | Doris |
    | 2 | Abbot |
    | 3 | Green |
    | 4 | Emerson |
    | 5 | Jeames |
    ±--------±--------+
    注意:
    如果学生人数是奇数,则不需要改变最后一个同学的座位。
    答案+结果:
    在这里插入图片描述
  • 小实战9
    题目:分数排名(难度:中等)
    编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
    创建以下score表:
    ±—±------+
    | Id | Score |
    ±—±------+
    | 1 | 3.50 |
    | 2 | 3.65 |
    | 3 | 4.00 |
    | 4 | 3.85 |
    | 5 | 4.00 |
    | 6 | 3.65 |
    ±—±------+
    例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):
    ±------±-----+
    | Score | Rank |
    ±------±-----+
    | 4.00 | 1 |
    | 4.00 | 1 |
    | 3.85 | 2 |
    | 3.65 | 3 |
    | 3.65 | 3 |
    | 3.50 | 4 |
    ±------±-----+
    答案:
    方法一:

MySQL变量法
mysql中变量不用事前申明,在用的时候直接用“@变量名”使用就可以了。
第一种用法 set @num=999; 或set @num:=888; //这里要使用变量来保存数据,直接使用@num变量
第二种用法 select @num:=1; 或 select @num:=字段名 from 表名 where ……
注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”,单个=会被解析为where后面的字段值比较

SELECT
  Score,
  @rank := @rank + (@prev <> (@prev := Score))  Rank
FROM
  score,
  (SELECT @rank := 0, @prev := -1) init
ORDER BY Score DESC;

解释:(利用变量来实现排名)
1.使用了@rank,@prev两个变量,一个表示排名,一个表示前一名的score分数
2.@rank := 0, @prev := -1 #对变量进行初始化
3.表达式@prev <> (@prev := Score)的取值轨迹为1,0,1,1,0,1,表示当前分数与前一分数进行比较,如果相同则为0,不同则为1
4.@rank := @rank +(@prev <> (@prev := Score)) 这条命令相当于 循环下的sum +=num;类似的原理。

SELECT
  Score,
  (@prev <> (@prev := Score)) Rank
FROM
  Scores,
  (SELECT @rank := 0, @prev := -1) init
ORDER BY Score desc

Score   Rank       
4.00	1
4.00	0
3.85	1
3.65	1
3.65	0
3.50	1
  • 小实战10——复杂项目
    题目:行程和用户(难度:困难)
    Trips 表中存所有出租车的行程信息。每段行程有唯一键 Id,Client_Id 和 Driver_Id 是 Users 表中 Users_Id 的外键。Status 是枚举类型,枚举成员为 (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’)。
    ±—±----------±----------±--------±-------------------±---------+
    | Id | Client_Id | Driver_Id | City_Id | Status |Request_at|
    ±—±----------±----------±--------±-------------------±---------+
    | 1 | 1 | 10 | 1 | completed |2013-10-01|
    | 2 | 2 | 11 | 1 | cancelled_by_driver|2013-10-01|
    | 3 | 3 | 12 | 6 | completed |2013-10-01|
    | 4 | 4 | 13 | 6 | cancelled_by_client|2013-10-01|
    | 5 | 1 | 10 | 1 | completed |2013-10-02|
    | 6 | 2 | 11 | 6 | completed |2013-10-02|
    | 7 | 3 | 12 | 6 | completed |2013-10-02|
    | 8 | 2 | 12 | 12 | completed |2013-10-03|
    | 9 | 3 | 10 | 12 | completed |2013-10-03|
    | 10 | 4 | 13 | 12 | cancelled_by_driver|2013-10-03|
    ±—±----------±----------±--------±-------------------±---------+
    Users 表存所有用户。每个用户有唯一键 Users_Id。Banned 表示这个用户是否被禁止,Role 则是一个表示(‘client’, ‘driver’, ‘partner’)的枚举类型。
    ±---------±-------±-------+
    | Users_Id | Banned | Role |
    ±---------±-------±-------+
    | 1 | No | client |
    | 2 | Yes | client |
    | 3 | No | client |
    | 4 | No | client |
    | 10 | No | driver |
    | 11 | No | driver |
    | 12 | No | driver |
    | 13 | No | driver |
    ±---------±-------±-------+
    写一段 SQL 语句查出 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率。基于上表,你的 SQL 语句应返回如下结果,取消率(Cancellation Rate)保留两位小数。
    ±-----------±------------------+
    | Day | Cancellation Rate |
    ±-----------±------------------+
    | 2013-10-01 | 0.33 |
    | 2013-10-02 | 0.00 |
    | 2013-10-03 | 0.50 |
    ±-----------±------------------+
    答案:
-- 创建Trips表
CREATE TABLE Trips(
id INT PRIMARY KEY,
Client_id INT,
Driver_id INT,
City_id INT,
Status ENUM('completed','cancelled_by_driver','cancelled_by_client'),
Request_at VARCHAR(50)
);

-- 插入数据
INSERT INTO Trips VALUES ('1', '1', '10', '1', 'completed', '2013-10-01');
INSERT INTO Trips VALUES ('2', '2', '11', '1', 'cancelled_by_driver', '2013-10-01');
INSERT INTO Trips VALUES ('3', '3', '12', '6', 'completed', '2013-10-01');
INSERT INTO Trips VALUES ('4', '4', '13', '6', 'cancelled_by_client', '2013-10-01');
INSERT INTO Trips VALUES ('5', '1', '10', '1', 'completed', '2013-10-02');
INSERT INTO Trips VALUES ('6', '2', '11', '6', 'completed', '2013-10-02');
INSERT INTO Trips VALUES ('7', '3', '12', '6', 'completed', '2013-10-02');
INSERT INTO Trips VALUES ('8', '2', '12', '12', 'completed', '2013-10-03');
INSERT INTO Trips VALUES ('9', '3', '10', '12', 'completed', '2013-10-03');
INSERT INTO Trips VALUES ('10', '4', '13', '12', 'cancelled_by_driver', '2013-10-03');

-- 查看Trips表
SELECT * FROM Trips; 

-- 创建Users表
CREATE TABLE Users(
Users_id INT PRIMARY KEY,
Banned varchar(20),
Role ENUM('client','driver','partner')
);

-- 插入数据
INSERT INTO Users VALUES ('1',  'No',  'client');
INSERT INTO Users VALUES ('2',  'Yes', 'client');
INSERT INTO Users VALUES ('3',  'No',  'client');
INSERT INTO Users VALUES ('4',  'No',  'client');
INSERT INTO Users VALUES ('10', 'No',  'driver');
INSERT INTO Users VALUES ('11', 'No',  'driver');
INSERT INTO Users VALUES ('12', 'No',  'driver');
INSERT INTO Users VALUES ('13', 'No',  'driver');

-- 查看Users表
SELECT * FROM users;

-- 实现代码
SELECT t.Request_at AS Day,
ROUND(sum((CASE WHEN t.Status LIKE 'cancelled%' THEN 1 ELSE 0 END))/count(*),2) AS 'Cancellation Rate' -- 如果是取消的就为1,否则为0,sum求和后除以当天的总单数,即为取消率。Round函数用来保留两位小数。
FROM Trips t
INNER JOIN Users u ON u.Users_Id =t.Client_Id AND u.Banned = 'No' -- 连接两张表
GROUP BY t.Request_at; -- 以订单时间分组


  • 小实战11
    题目:各部门前3高工资的员工(难度:中等)
    将项目7中的employee表清空,重新插入以下数据(其实是多插入5,6两行):
    ±—±------±-------±-------------+
    | Id | Name | Salary | DepartmentId |
    ±—±------±-------±-------------+
    | 1 | Joe | 70000 | 1 |
    | 2 | Henry | 80000 | 2 |
    | 3 | Sam | 60000 | 2 |
    | 4 | Max | 90000 | 1 |
    | 5 | Janet | 69000 | 1 |
    | 6 | Randy | 85000 | 1 |
    ±—±------±-------±-------------+
    编写一个 SQL 查询,找出每个部门工资前三高的员工。例如,根据上述给定的表格,查询结果应返回:
    ±-----------±---------±-------+
    | Department | Employee | Salary |
    ±-----------±---------±-------+
    | IT | Max | 90000 |
    | IT | Randy | 85000 |
    | IT | Joe | 70000 |
    | Sales | Henry | 80000 |
    | Sales | Sam | 60000 |
    ±-----------±---------±-------+

此外,请考虑实现各部门前N高工资的员工功能。

CREATE TABLE IF NOT EXISTS Employee(
	Id SMALLINT PRIMARY KEY AUTO_INCREMENT,
	Name VARCHAR(20) NOT NULL,
	Salary INT NOT NULL,
	DepartmentId TINYINT NOT NULL
);
CREATE TABLE IF NOT EXISTS Department(
	Id SMALLINT PRIMARY KEY AUTO_INCREMENT,
	Name VARCHAR(20) NOT NULL
);

INSERT Employee(Name,Salary,DepartmentId)
Values('Joe',70000,1),
			('Henry',80000,2),
			('Sam',60000,2),
			('Max',90000,1);

INSERT Department(Name)
Values('IT'),
			('Sales');
SELECT d.Name as Department,e.Name as Employee,e.Salary
FROM Employee e,Department d
WHERE e.DepartmentId = d.Id 
and e.Salary = (SELECT MAX(Employee.Salary)
									FROM Employee
									WHERE Employee.DepartmentId = d.Id);	
  • 小实战12
    题目:分数排名 - (难度:中等)
    依然是昨天的分数表,实现排名功能,但是排名是非连续的,如下:
    ±------±-----+
    | Score | Rank |
    ±------±-----+
    | 4.00 | 1 |
    | 4.00 | 1 |
    | 3.85 | 3 |
    | 3.65 | 4 |
    | 3.65 | 4 |
    | 3.50 | 6 |
    ±------±-----
SELECT
  Score,
  @rank := @rank + (@prev <> (s.Score)) * @count  Rank,
(CASE 
WHEN (@prev <> (@prev := Score)) THEN @count := 1
ELSE @count := @count + 1  END) Count
FROM
  score s,
  (SELECT @rank := 0, @prev := -1, @count := 1) init
ORDER BY Score DESC;

猜你喜欢

转载自blog.csdn.net/weixin_41903171/article/details/88982283