假设表格如下:
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');
然后,在其中以获得所需的输出可以写成查询的方法之一是:
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
输出:
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
您可以讨好忽略来自输出buffer_id
列 - 这是风马牛不相及的结果,但需要的rank
复位。
SQL Fiddle Demo
说明:
@id
变量跟踪每一个ID的行中,基于输出的排序顺序。在最初的迭代中,我们将其设置为可能在最终结果中获得的第一条记录的id
。见子查询SELECT q2.id FROM q43381823 AS q2 ORDER BY q2.id LIMIT 1
@rank
设置为0
最初,默认为递增结果集中的所有后续行。然而,当id
变化,我们重置回1
。请在查询中查看CASE - WHEN - ELSE
结构。
最终输出首先按id
然后按dt
排序。这确保了@rank
设置递增,以后每场dt
同id
内,但每当一个新的id
组开始在结果集中显示被重置为1
。
我爱你!非常感谢。我从来不会想到这一点。特别感谢您的出色解释。 –
谢谢。很高兴帮助! –