在 MySQL 中按顺序、分组和按日期枚举记录

Mon*_*eck 3 mysql group-by enumerate

这似乎是一个如此简单的问题,我害怕我可能会被重复的问题锤击打,但这是我所拥有的:

ID  Date
1   1/11/01
1   3/3/03
1   2/22/02
2   1/11/01
2   2/22/02
Run Code Online (Sandbox Code Playgroud)

我需要做的就是根据日期枚举记录,并按ID! 像这样:

ID  Date    Num
1   1/11/01 1
1   3/3/03  3
1   2/22/02 2
2   1/11/01 1
2   2/22/02 2
Run Code Online (Sandbox Code Playgroud)

这与这个问题非常相似,但它对我不起作用。会很棒,但它不是 MySQL。

我尝试使用group by但它不起作用,如

SELECT ta.*, count(*) as Num
FROM temp_a ta
GROUP BY `ID` ORDER BY `ID`;  
Run Code Online (Sandbox Code Playgroud)

这显然不会运行,因为GROUP BY总是结果为一个值。

非常感谢任何建议。

Dhr*_*ena 5

让我们假设表格如下:

CREATE TABLE q43381823(id INT, dt DATE);
INSERT INTO q43381823 VALUES
(1, '2001-01-11'),
(1, '2003-03-03'),
(1, '2002-02-22'),
(2, '2001-01-11'),
(2, '2002-02-22');
Run Code Online (Sandbox Code Playgroud)

然后,可以编写获取所需输出的查询的方法之一是:

SELECT q.*,  
    CASE WHEN (
            IF(@id != q.id, @rank := 0, @rank := @rank + 1)
         ) >=1 THEN @rank
         ELSE @rank := 1 
    END as rank,
    @id := q.id AS buffer_id
FROM q43381823 q
CROSS JOIN (
    SELECT  @rank:= 0, 
        @id  := (SELECT q2.id FROM q43381823 AS q2 ORDER BY q2.id LIMIT 1)
    ) x
ORDER BY q.id, q.dt
Run Code Online (Sandbox Code Playgroud)

输出:

  id  |    dt        |   rank  |    buffer_id 
-------------------------------------------------    
  1   |  2001-01-11  |    1    |       1    
  1   |  2002-02-22  |    2    |       1
  1   |  2003-03-03  |    3    |       1
  2   |  2001-01-11  |    1    |       2
  2   |  2002-02-22  |    2    |       2
Run Code Online (Sandbox Code Playgroud)

您可以忽略buffer_id输出中的列 - 它与结果无关,但需要重置rank.

SQL 小提琴演示



解释:

  • @id变量根据输出的排序顺序跟踪行中的每个 id。在初始迭代中,我们将其设置id为最终结果中可能获得的第一条记录。查看子查询SELECT q2.id FROM q43381823 AS q2 ORDER BY q2.id LIMIT 1

  • @rank0最初设置为,并且默认情况下为结果集中的每个后续行递增。但是,当id发生变化时,我们将其重置回1. 请参阅CASE - WHEN - ELSE查询中的构造。

  • 最终输出首先按 排序id,然后按 排序dt。这可确保@rankdt同一 中的每个后续字段递增设置id,但1每当新id组开始出现在结果集中时都会重置为。