-2

我在一轮面试中遇到了这个问题。表具有以下列。

ID
1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
20
22
23
24
26

问题是创建一个以“1”开头的新列,只要有 5 的倍数,就在下一个 ID 上递增。所以预期的输出是

ID 结果
1 1
2 1
3 1
4 1
5 1
6 2
7 2
8 2
9 2
11 2
12 2
13 2
14 2
15 2
16 3
17 3
18 3
19 3
20 3
22 4
23 4
24 4
26 4
4

3 回答 3

2

您可以组合两个窗口函数:LAG()SUM()。例如:

select id, 
  1 + sum(case when lid % 5 = 0 then 1 else 0 end) over(order by id) as v
from (
  select *, lag(id) over(order by id) as lid from t
) x
order by id

结果:

 id  v 
 --  - 
 1   1 
 2   1 
 3   1 
 4   1 
 5   1 
 6   2 
 7   2 
 8   2 
 9   2 
 11  2 
 12  2 
 13  2 
 14  2 
 15  2 
 16  3 
 17  3 
 18  3 
 19  3 
 20  3 
 22  4 
 23  4 
 24  4 
 26  4 

请参阅DB Fiddle上的运行示例。

于 2021-02-17T03:42:48.617 回答
1

例如,对于 MySQL 5+,您可以使用

SELECT id, (@result := COALESCE( @result + !(id % 5), 1 )) - !(id % 5) result
FROM t
CROSS JOIN (SELECT @result := NULL) init_variable
ORDER BY id

对于 MySQL 8+ 使用

SELECT id, 1 + SUM(!(id % 5)) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) resuls
FROM t
于 2021-02-17T05:13:11.503 回答
0

您可以在没有子查询的情况下执行此操作:

select t.*,
       1 + sum( (id % 5) = 0 ) over (order by id) - (id % 5 = 0)
from t
order by id;

这里的逻辑是什么?计算直到这一行的“5”的累积和。然后减去这一行的值,因为增量对下一行生效。

使用窗口框架子句编写它也很诱人,但最终会稍微复杂一些,因为第一个值是NULL

select t.*,
       1 + coalesce(sum( (id % 5) = 0 ) over (order by id rows between unbounded preceding and 1 preceding), 0)
from t
order by id;

是一个 db<>fiddle。

于 2021-02-17T13:11:56.380 回答