【问题标题】:sql window function every time partionion value changes每次分区值更改时的sql窗口函数
【发布时间】:2022-01-24 14:10:55
【问题描述】:

是否可以写一个窗口函数,每次分区值变化时进行分区?

例如:

create table test (id int, i int);

insert into test values (1, 1), (2, 0),(3, 0),(4, 1),(5, 1),(6, 1),(7, 0),(8, 0),(9, 1);

select
    id,
    i,
    row_number() over (partition by i order by id asc) rn
from 
    test
order by 
    id asc;

会给我以下结果:

id  i   rn
----------
1   1   1
2   0   1
3   0   2
4   1   2
5   1   3
6   1   4
7   0   3
8   0   4
9   1   5

但是,当i 的值根据我的排序顺序发生更改时,我希望能够再次重新启动计数器,无论它是否已经出现。

例如,期望的结果是这样的:

id  i   rn
----------
1   1   1
2   0   1
3   0   2
4   1   1
5   1   2
6   1   3
7   0   1
8   0   2
9   1   1

同样的原则也适用于其他窗口函数,例如累积和。

我真的不想为此循环,而且我找不到合适的窗口函数。

谢谢

【问题讨论】:

  • 这被称为间隙和孤岛问题。搜索一下方法,你应该会找到你正在寻找的东西。

标签: sql sql-server tsql


【解决方案1】:

您可以通过添加包含先前i 的列(使用lag(i))来实现此目的,然后保持“翻转”的总次数(当前 i 前 i)。翻转次数相同的行属于同一组。

with u as 
(select id, i, lag(i) over (order by id) as previousi
from test),
v as
(select id,
i,
sum(case when i = previousi then 0 else 1 end)
over (order by id rows unbounded preceding) as flips
from u)
select id, i, row_number() over (partition by flips order by id) as rn
from v

Fiddle

【讨论】:

  • 谢谢。我最终用 lag 函数实现了这种方法。
  • 抱歉,一定是错过了按钮什么的
【解决方案2】:

这个问题是一个间隙和孤岛问题。我从这个问题中得出了我的解决方案:

Reset Row Number on value change, but with repeat values in partition

我的查询如下所示:

with cte as (
  SELECT id, i, 
    ROW_NUMBER() OVER (PARTITION BY i order by id) rn1
  FROM test
)
SELECT id, i, 
    ROW_NUMBER() OVER (PARTITION BY CAST((id - rn1) as CHAR(100)) || CAST(i as CHAR(100)) ORDER BY id) rn
FROM cte
ORDER BY 
    id

我扩展了您的数据集以验证答案。我在 Tim Biegeleisen 的回答中使用了相同的概念。我得到 i 的行号,然后从 id 中减去它。这些差异应该导致每个具有相同 i 的 id 号的值相同,直到 i 再次切换。我在 8,0 处遇到了一个问题,其中 row_number 为 4(导致差异为 4)和 9,1 和 row_number 为 5(也导致差异为 4)。为了解决这种情况,我将差异转换为字符串并将 I 连接起来,形成一个唯一的 id,我们可以对其进行分区。

您可以在这个 dbfiddle 中查看它: https://www.db-fiddle.com/f/hnGUTZGLvRQ5JoSCHozAhs/0

【讨论】:

    猜你喜欢
    • 2018-09-12
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 2018-12-16
    • 2014-05-24
    • 2023-03-06
    相关资源
    最近更新 更多