[英]SQL to select a new column based on certain conditions
create table so (
id int
,column1 int
,column2 varchar(1)
);
insert into so values
(1, 1, 'Y')
,(2, 1, 'Y')
,(3, 1, 'N')
,(4, 1, 'N')
,(5, 1, 'Y')
,(6, 1, 'Y')
,(7, 1, 'Y')
,(8, 1, 'Y')
,(9, 2, 'Y')
,(10, 2, 'Y')
,(11, 2, 'N');
with str as (
select
*
,min(id) over (partition by column1) id_start
,case column2
when 'N'
then row_number() over (
partition by column1
order by column2, id
)
else null
end n_value
from
so
), cls as (
select
*
,case
when id_start = id
then 1
else
coalesce(max(n_value) over (
partition by column1
order by id
rows between unbounded preceding and current row
) + 1 ,1)
end column3
from
str
)
select
id
,column1
,column2
,column3
from
cls
order by
id
如其他评论和答案所示,您需要一个订购密钥才能使此操作成功。 我在 DDL 中人为地创建了一个,尽管您当然可以使用row_number()
和不同的排序键自己构建另一个。
答案中的str
CTE 提供了两个非常关键的列,它们从排序中提取隐式数据: id_start
和n_value
。
id_start
:提供排序键值id
,其中每个column1
发生变化。 在您对column3
的定义中,这基本上是您的第三个项目符号。
n_value
:我们需要知道column3
的值变化的次数。 根据您的定义,这仅在column2 = 'N'
时发生,因此该列返回在column1
分区中发生这种情况的次数。
一旦我们有了这两个数据,避免这个问题的迭代就很简单了: column3
是所有先前n_value
的最大值加一。 一个例外是当 Y 紧跟在分区的开头时,在这种情况下column3
始终为 1。(这是通过合并解决的。)
这是一个使用 PostgreSQL 的SqlFiddle 。 Netezza 是一个变体,所以语法在那里仍然有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.