这是我在Sql Server中使用的代码,我想在Mysql中使用相同的代码
不幸的是,MySQL 5没有等级功能。我尝试了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
答案 0 :(得分:0)
我可以随意添加更多数据,以确保满足所有测试用例。
创建表MysqlTemp ( 编号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的记录。第一条记录将只有1条小于或=的记录。第二个记录的2个记录少于或=。以此类推。那才算是排名。
下面是order by子句的第二部分。
and (coalesce(col3,'Z') < coalesce(m1.col3,'Z') or id <= m1.id)
为什么这里有额外或条件?因为id>用于第二和第三条记录,所以您将错过需要计数的第一条记录。所以一个或。
我知道那会有点模糊。分别尝试查询每个部分,您将了解。