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总是结果为一个值。
非常感谢任何建议。
让我们假设表格如下:
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.
解释:
@id变量根据输出的排序顺序跟踪行中的每个 id。在初始迭代中,我们将其设置id为最终结果中可能获得的第一条记录。查看子查询SELECT q2.id FROM q43381823 AS q2 ORDER BY q2.id LIMIT 1
@rank0最初设置为,并且默认情况下为结果集中的每个后续行递增。但是,当id发生变化时,我们将其重置回1. 请参阅CASE - WHEN - ELSE查询中的构造。
最终输出首先按 排序id,然后按 排序dt。这可确保@rank为dt同一 中的每个后续字段递增设置id,但1每当新id组开始出现在结果集中时都会重置为。
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |