mysql - 按列分组的查询结果的行号

标签 mysql

我有一个包含以下列的表格: 编号 | fk_id |接收日期

可能有多条记录具有共同的fk_id,表示相关表中的外键id。

我需要创建一个查询,为每条记录分配一个行号,按 fk_id 分组,按 rcv_date 排序。

我最初是从以下查询开始的,它非常适合排序和分配行号:

SELECT @row:=@row +1 AS ordinality, c.fk_id, rcv_date
FROM (SELECT @row:=0) r, mytable c
ORDER BY rcv_date

但是——行计数和排序是在整个数据集中完成的。我需要计数在一个共同的 fk_id 内。例如,将返回以下示例数据(第一列表示行数/序数):

1 | 5 | 2011-10-01
2 | 5 | 2011-10-14
3 | 5 | 2011-11-02
4 | 5 | 2011-12-17
1 | 8 | 2011-09-03
2 | 8 | 2011-11-12
1 | 9 | 2011-10-08
2 | 9 | 2011-10-10
3 | 9 | 2011-11-19

中间一列代表fk_id。如您所见,排序和行数在 fk_id“分组”内。

更新 我有一个似乎有效的查询,但想知道是否可以改进它:

SELECT IF(@last = c.fk_id, @row:=@row +1, @row:=1) AS ordinality, @last:=c.fk_id, c.fk_id, rcv_date
FROM (SELECT @row:=0) r, (SELECT @last:=0) l, mytable c
ORDER BY c.fk_id, rcv_date

所以它所做的是按 fk_id 排序,然后按 rcv_date 排序——这实际上处理了我的分组。然后我使用第二个变量将前一条记录中的 fk_id 与当前记录进行比较:如果相同,则增加该行;否则如果不同,我们重置为 1。

我对真实数据的测试似乎有效。不过,我怀疑这是一个非常低效的查询——所以如果有人有改进它的想法,或者看到可能存在的缺陷,我很乐意听到。

最佳答案

这应该非常简单。

SELECT (CASE WHEN @fk <> fk_id THEN @row:=1 ELSE @row:=@row + 1 END) AS ordinality, 
       @fk:=fk_id, rcv_date
FROM   (SELECT @row:=0) AS r, 
       (SELECT @fk:=0) AS f, 
       (SELECT fk_id, rcv_date FROM files ORDER BY fk_id, rcv_date) AS t

我首先按 fk_id 进行排序,以确保您所有的外键都放在一起(如果它们不在表中怎么办?),然后我按照您的首选顺序进行排序,即按 rcv_date。查询检查 fk_id 是否有变化,如果有,则行号变量设置为 1,否则变量递增。它在 case 语句中处理。请注意,@fk:=fk_id 是在大小写检查之后完成的,否则它会影响行号。

编辑:刚刚注意到您自己的解决方案恰好与我最终得到的相同。荣誉! :)

关于mysql - 按列分组的查询结果的行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13216427/

相关文章:

php - 获得最独特的结果,获得奇怪的..结果

MYSQL-错误#1054

mysql - 将 User-Agent 字符串的哈希存储在 MySQL 表中 : insert if not exists, 返回 id

mysql - 从 2 个带有重复记录的 MySQL 表中查询数据

php - 我担心 SQL 注入(inject)。这样安全吗?

java转mysql jdbc连接问题

mysql - group by 无法正确连接两个表

php - 未定义索引 : id in C:\xampp\htdocs\test\edit. php 第 13 行

php - 为什么我的查询不执行?

mysql - 一个相当复杂的自增