Mysql 列中每个重复项的递增计数器
我有一张桌子:Mysql 列中每个重复项的递增计数器,mysql,sql,duplicates,Mysql,Sql,Duplicates,我有一张桌子: id | value 1 | - 1 | a 2 | b 1 | c 3 | d 2 | e 然后我需要一个计数器列,对于id列中的每个不同值,它从1开始 所需的选择结果: id | value | counter 1 | - | 1 1 | a | 2 2 | b | 1 1 | c | 3 3 | d | 1 2 | e | 2 我所发现的只是计算重复的数量等,而不是对特定列的每个重复的递增计数器…?
id | value
1 | -
1 | a
2 | b
1 | c
3 | d
2 | e
然后我需要一个计数器列,对于id列中的每个不同值,它从1开始
所需的选择结果:
id | value | counter
1 | - | 1
1 | a | 2
2 | b | 1
1 | c | 3
3 | d | 1
2 | e | 2
我所发现的只是计算重复的数量等,而不是对特定列的每个重复的递增计数器…?您试图完成的任务称为排名。不幸的是,MySQL没有像SQL Server中那样的排名函数
ROW\u NUMBER()
,densite\u RANK()
等
您可以尝试下面的MySQL查询
SELECT t.ID, t.Value, count(*) as Counter
FROM tableName t
JOIN tableName b ON t.ID = b.ID AND t.Value >= b.Value
GROUP BY t.ID, t.Value
如果您不关心排序,只关心相应的行号,请使用如下变量:
SELECT
t.*,
@i:=IF(id=@id, @i+1, 1) AS num,
@id:=id
FROM
t
CROSS JOIN (SELECT @i:=0, @id:=0) AS init
ORDER BY id
我希望这将是有用的:)这将为您完成以下工作:
SELECT [id]
,[value]
,ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY value) AS 'counter'
FROM [TableName]
行号将添加编号。
PARTITION BY子句允许我们在对ROW_NUMBER()的调用中对结果进行分组,而无需通过group BY对结果进行分组。它只是告诉行号在进行计数时使用什么分组
对于MySql,您可以使用以下链接:
就你而言:
SET @row_number:=0;
SET @id:='';
SELECT @row_number:=CASE WHEN @id=id THEN @row_number+1 ELSE 1 END AS row_number , @id:=id AS id, value
FROM TableName
ORDER BY id;
MySQL中的一些黑客可以做到这一点,但是IMO应该考虑在应用程序中做它。@ Vatev实际上是在My.CNF中配置的初始化文件中的一些查询来初始化更快的访问的内存表;我真的不能使用单独的脚本吗?id的值是静态的,或者可以添加新的id???@RonaldAlexanderKailola id是静态的(每次更改时都会完全重新生成内存表;cron每天运行一次)很好,只是一个小问题:在20k行表上5分钟后还没有完成;你最终会有更快的吗?对不起,我在SQL Server上工作,对MySQL不太了解:(如果没有适当的索引,这将很慢,因为
JOIN
如何与指定的条件一起工作。顺便说一句,我们已经对列进行了索引。如果没有,请参阅在使用连接时进行索引可以显著提高性能。使用更多重复ID时,连接将变得更慢。会话变量方法(@AlmaDo的答案)将总是更快。这将起作用,是的-但是完整的SACN
在没有索引的表上是有保证的。应该比连接
更快,但是在一个大表上花费不到一秒钟的时间,这是完美的:-)如果您关心订购,您可以将其包装在另一个SELECT And order by任意内容中。@Vatev是的,这就是我正在做的。^我已经找到了一个,但我有mysql(查看标签)。这是对Oracle
和SQL Server
的很好的查询。好吧,也许删除SQL标记会更好。此外,也许这个链接对于在MySQL中找到等效的解决方案会很有用:问题被标记为MySQL
,不是吗?这是用SQL Server查询回答的错误原因,因为它的特定语法不会“不适用于mysql。因此,尽管它已链接到sql,但对于特定的标记问题,使用非工作语法回答仍然是不正确的(简而言之:mysql
overridessql
)
SET @row_number:=0;
SET @id:='';
SELECT @row_number:=CASE WHEN @id=id THEN @row_number+1 ELSE 1 END AS row_number , @id:=id AS id, value
FROM TableName
ORDER BY id;