Mysql 具有两列的排名函数并按第三列排序
Mysql rank funtion with two Columns and order by third column
这是我在 Sql 服务器中使用的代码,我想在 Mysql
中使用相同的代码
很遗憾Mysql5没有排名功能。我试过 google 仍然没有帮助按多列分区和按第三列排序
SELECT
A.ID, A.COL1, A.COL2, A.COL3
FROM (
SELECT
ID, COL1, COL2, COL3, ROW_NUMBER() OVER (PARTITION BY COL1, COL2 ORDER BY COL3 DESC,ID) AS RN
FROM #temp) A
WHERE A.RN=1
能否请大家帮忙在mysql
中使用
SELECT * FROM MysqlTemp
CREATE TEMPORARY TABLE MysqlTemp
(
ID INT
, Col1 VARCHAR(20)
, Col2 VARCHAR(20)
, Col3 VARCHAR(30)
)
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (1,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (2,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (3,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (4,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (5,'Hey','Hey');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (6,'Hey','Hey','B45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (7,'Howdy','Howdy','V44');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (8,'Howdy','Howdy');
预期值为 1、3、6、7
我冒昧地添加了更多数据以确保我满足所有测试用例。
CREATE TABLE MysqlTemp
(
ID INT
, Col1 VARCHAR(20)
, Col2 VARCHAR(20)
, Col3 VARCHAR(30)
) ;
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (1,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (2,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (3,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (4,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (5,'Hey','Hey');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (6,'Hey','Hey','B45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (7,'Howdy','Howdy','V44');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (8,'Howdy','Howdy');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (9,'Howdy','Howdy');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (10,'Howdy','Howdy','V45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (11,'ROWDY','ROWDY','X45');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (12,'ROWDY','ROWDY');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (13,'ROWDY','ROWDY');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (14,'ROWDY','ROWDY','X44');
select m1.*,
(select count(1) from MysqlTemp m2
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
and col1 = m1.col1
and col2 = m1.col2
) as rnk
from MysqlTemp m1
ID Col1 Col2 Col3 rnk
1 Hi Hi A21 1
2 Hi Hi A21 2
3 Hello Hello (null) 1
4 Hello Hello (null) 2
5 Hey Hey (null) 2
6 Hey Hey B45 1
7 Howdy Howdy V44 1
8 Howdy Howdy (null) 3
9 Howdy Howdy (null) 4
10 Howdy Howdy V45 2
11 ROWDY ROWDY X45 2
12 ROWDY ROWDY (null) 3
13 ROWDY ROWDY (null) 4
14 ROWDY ROWDY X44 1
说明:
在 mysql 中,一种生成排名的方法是使用相关子查询。
这部分针对查询中的每条记录执行
select count(1) from MysqlTemp m2
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
and col1 = m1.col1
and col2 = m1.col2
这部分确保连接只处理符合此条件的记录。基本上,这就是分区条款。
and col1 = m1.col1
and col2 = m1.col2
这部分本来可以很简单<=,因为你有空值,你能达到的最高值用于比较空值。
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
到目前为止,我们正在尝试统计同一分区内所有小于col3 的记录。第一条记录将只有一条记录小于或 =。第二条记录将有 2 条记录小于或 =。很快。这就是排名。
以下部分为order by子句的第二部分。
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
这里为什么有额外的或条件?因为 id > 对于第二条和第三条记录,你会错过需要计算的第一条记录。所以一个或.
我知道它会有点模糊。分别尝试每个部分的查询,您就会明白。
这是我在 Sql 服务器中使用的代码,我想在 Mysql
中使用相同的代码很遗憾Mysql5没有排名功能。我试过 google 仍然没有帮助按多列分区和按第三列排序
SELECT
A.ID, A.COL1, A.COL2, A.COL3
FROM (
SELECT
ID, COL1, COL2, COL3, ROW_NUMBER() OVER (PARTITION BY COL1, COL2 ORDER BY COL3 DESC,ID) AS RN
FROM #temp) A
WHERE A.RN=1
能否请大家帮忙在mysql
中使用SELECT * FROM MysqlTemp
CREATE TEMPORARY TABLE MysqlTemp
(
ID INT
, Col1 VARCHAR(20)
, Col2 VARCHAR(20)
, Col3 VARCHAR(30)
)
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (1,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (2,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (3,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (4,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (5,'Hey','Hey');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (6,'Hey','Hey','B45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (7,'Howdy','Howdy','V44');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (8,'Howdy','Howdy');
预期值为 1、3、6、7
我冒昧地添加了更多数据以确保我满足所有测试用例。
CREATE TABLE MysqlTemp
(
ID INT
, Col1 VARCHAR(20)
, Col2 VARCHAR(20)
, Col3 VARCHAR(30)
) ;
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (1,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (2,'Hi','Hi','A21');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (3,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (4,'Hello','Hello');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (5,'Hey','Hey');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (6,'Hey','Hey','B45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (7,'Howdy','Howdy','V44');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (8,'Howdy','Howdy');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (9,'Howdy','Howdy');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (10,'Howdy','Howdy','V45');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (11,'ROWDY','ROWDY','X45');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (12,'ROWDY','ROWDY');
INSERT INTO MysqlTemp (ID,Col1,Col2) VALUES (13,'ROWDY','ROWDY');
INSERT INTO MysqlTemp (ID,Col1,Col2,Col3) VALUES (14,'ROWDY','ROWDY','X44');
select m1.*,
(select count(1) from MysqlTemp m2
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
and col1 = m1.col1
and col2 = m1.col2
) as rnk
from MysqlTemp m1
ID Col1 Col2 Col3 rnk
1 Hi Hi A21 1
2 Hi Hi A21 2
3 Hello Hello (null) 1
4 Hello Hello (null) 2
5 Hey Hey (null) 2
6 Hey Hey B45 1
7 Howdy Howdy V44 1
8 Howdy Howdy (null) 3
9 Howdy Howdy (null) 4
10 Howdy Howdy V45 2
11 ROWDY ROWDY X45 2
12 ROWDY ROWDY (null) 3
13 ROWDY ROWDY (null) 4
14 ROWDY ROWDY X44 1
说明: 在 mysql 中,一种生成排名的方法是使用相关子查询。
这部分针对查询中的每条记录执行
select count(1) from MysqlTemp m2
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
and col1 = m1.col1
and col2 = m1.col2
这部分确保连接只处理符合此条件的记录。基本上,这就是分区条款。
and col1 = m1.col1
and col2 = m1.col2
这部分本来可以很简单<=,因为你有空值,你能达到的最高值用于比较空值。
where coalesce(col3,'Z') <= coalesce(m1.col3,'Z')
到目前为止,我们正在尝试统计同一分区内所有小于col3 的记录。第一条记录将只有一条记录小于或 =。第二条记录将有 2 条记录小于或 =。很快。这就是排名。
以下部分为order by子句的第二部分。
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
这里为什么有额外的或条件?因为 id > 对于第二条和第三条记录,你会错过需要计算的第一条记录。所以一个或.
我知道它会有点模糊。分别尝试每个部分的查询,您就会明白。