在MySQL中有一个很好的方法来复制SQL Server函数ROW_NUMBER()?
例如:
SELECT
col1, col2,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
FROM Table1
然后,例如,我可以添加一个条件,将intRow限制为1,以获得每个(col1, col2)对的col3最高的单行。
在MySQL中有一个很好的方法来复制SQL Server函数ROW_NUMBER()?
例如:
SELECT
col1, col2,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
FROM Table1
然后,例如,我可以添加一个条件,将intRow限制为1,以获得每个(col1, col2)对的col3最高的单行。
当前回答
看看这篇文章,它展示了如何在MySQL中使用分区by模拟SQL ROW_NUMBER()。我在WordPress实现中遇到了同样的场景。我需要ROW_NUMBER(),但它不在那里。
http://www.explodybits.com/2011/11/mysql-row-number/
本文中的示例使用了一个按字段划分的分区。要按额外的字段进行分区,你可以这样做:
SELECT @row_num := IF(@prev_value=concat_ws('',t.col1,t.col2),@row_num+1,1) AS RowNumber
,t.col1
,t.col2
,t.Col3
,t.col4
,@prev_value := concat_ws('',t.col1,t.col2)
FROM table1 t,
(SELECT @row_num := 1) x,
(SELECT @prev_value := '') y
ORDER BY t.col1,t.col2,t.col3,t.col4
使用concat_ws处理null。我使用int、date和varchar对3个字段进行了测试。希望这能有所帮助。查看这篇文章,因为它分解了这个查询并解释了它。
其他回答
从MySQL 8.0.0及以上版本,您可以本机使用窗口函数。
1.4 MySQL 8.0的新特性:
窗口函数。 MySQL现在支持窗口函数,对于查询中的每一行,使用与该行相关的行执行计算。这些函数包括RANK()、LAG()和NTILE()。此外,一些现有的聚合函数现在可以用作窗口函数;例如SUM()和AVG()。
ROW_NUMBER() over_clause:
返回分区内当前行的编号。行号从1到分区行数。 ORDER BY影响行编号的顺序。没有ORDER BY,行编号是不确定的。
演示:
CREATE TABLE Table1(
id INT AUTO_INCREMENT PRIMARY KEY, col1 INT,col2 INT, col3 TEXT);
INSERT INTO Table1(col1, col2, col3)
VALUES (1,1,'a'),(1,1,'b'),(1,1,'c'),
(2,1,'x'),(2,1,'y'),(2,2,'z');
SELECT
col1, col2,col3,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS intRow
FROM Table1;
DBFiddle演示
MySQL从8.0+版本开始支持ROW_NUMBER()。
如果使用MySQL 8.0或更高版本,请检查ROW_NUMBER()函数。 否则,您将使用模拟ROW_NUMBER()函数。
row_number()是一个排序函数,返回一行的顺序编号,第一行从1开始。
对于旧版本,
SELECT t.*,
@rowid := @rowid + 1 AS ROWID
FROM TABLE t,
(SELECT @rowid := 0) dummy;
我认为你可以在这里使用DENSE_RANK()函数。 例子:
select `score`, DENSE_RANK() OVER( ORDER BY score desc ) as `rank` from Scores;
https://www.mysqltutorial.org/mysql-window-functions/mysql-dense_rank-function/
查询mysql中的row_number
set @row_number=0;
select (@row_number := @row_number +1) as num,id,name from sbs
也有点晚了,但今天我有同样的需要,所以我在谷歌上搜索了一下,最后在Pinal Dave的文章http://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/中找到了一个简单的一般方法
我想把重点放在Paul最初的问题上(这也是我的问题),所以我把我的解决方案总结为一个工作示例。
因为我们想要在两个列上进行分区,我将在迭代期间创建一个SET变量来识别是否启动了一个新组。
SELECT col1, col2, col3 FROM (
SELECT col1, col2, col3,
@n := CASE WHEN @v = MAKE_SET(3, col1, col2)
THEN @n + 1 -- if we are in the same group
ELSE 1 -- next group starts so we reset the counter
END AS row_number,
@v := MAKE_SET(3, col1, col2) -- we store the current value for next iteration
FROM Table1, (SELECT @n := 0, @v := NULL) r -- helper table for iteration with startup values
ORDER BY col1, col2, col3 DESC -- because we want the row with maximum value
) x WHERE row_number = 1 -- and here we select exactly the wanted row from each group
3意味着在MAKE_SET的第一个参数,我想在SET中的值(3=1|2)。 当然,如果没有两个或更多列来构造组,则可以取消MAKE_SET操作。结构完全相同。这对我来说是必要的。非常感谢Pinal Dave的清晰演示。