select
column1,
lag(column1) over(order by
to_number(substr(column1, instr(column1, '_') + 1)),
to_number(substr(column1, 1, instr(column1, '_') - 1))
) column3
from mytable
db小提琴演示:
with mytable as (
select '2_2020' column1 from dual
union all select '1_2020' from dual
union all select '52_2019' from dual
)
select
column1,
lag(column1) over(order by
to_number(substr(column1, instr(column1, '_') + 1)),
to_number(substr(column1, 1, instr(column1, '_') - 1))
) column3
from mytable
select col,
max(col) over (order by seqnum range between 1 preceding and 1 preceding)
from (select t.*, dense_rank() over (order by to_date(col, 'DDD_YYYY')) as seqnum
from t
) t;
with
sample_data(column1) as (
select '2_2020' from dual union all
select '1_2020' from dual union all
select '52_2019' from dual
)
select column1,
lead(column1)
over (order by to_date(column1, 'mi_yyyy') desc) as my_column,
to_char(lead(to_date(column1, 'mi_yyyy'))
over (order by to_date(column1, 'mi_yyyy') desc), 'fmmi') as column3
from sample_data
;
COLUMN1 MY_COLUMN COLUMN3
--------- --------- ---------
2_2020 1_2020 1
1_2020 52_2019 52
52_2019
5条答案
按热度按时间ldioqlga1#
如果你不关心几个世纪前历法的变化,那么你可以通过正则表达式得到数字
zlwx9yxi2#
你可以用
lag()
-但是您需要正确地拆分字符串并将部分转换为数字,以便可以使用它们对记录进行排序:db小提琴演示:
qyzbxkaa3#
这是一个糟糕的格式,因为它不保留顺序。我建议将其更改为yyyy\u ww——因此值将为2019\u 52、2020\u 01、2020\u 02。然后你可以简单地使用:
如果没有这一点,什么是最好的方式,使之成为一种格式,保持秩序?不幸的是,甲骨文
to_date()
不允许输入周数。但它确实允许输入一年中的某一天,并保留了顺序。因此您可以使用:这是一把小提琴。
如果表中有重复的数据,并且仍然希望数据中包含前一周的数据,那么这就更棘手了。这里有一个解决方案:
30byixjq4#
下面是一个sqlfiddle演示
ecfdbz9o5#
你可以利用最大周数(52或53)小于最大分钟数(59)的事实来使用黑客攻击。即使你的第一个数字代表周,为了这个查询,假装它代表分钟。然后可以使用不完整的日期格式模型('mi\u yyyy')在字符串和日期数据类型之间进行转换。oracle为其他组件提供默认值:当前月份
'mm'
,天01
为了'dd'
,小时00
一小时,一秒00
一秒钟。然后,您可以按这样构造的“日期”排序—无论第一个组件是“周数”还是“小时数”,顺序都是相同的。如果oracle允许使用日期格式模型,这将简单得多
'iw_yyyy'
,但事实并非如此。还要注意的是,由于我们希望按降序显示输出,所以我在分析函数中使用降序(因此,我必须使用
lead()
而不是lag()
). 这避免了对行进行两次排序的需要(一次按升序排列用于分析函数,另一次按降序排列用于最终输出)。正如我在你的问题下的评论中所说,我认为问题要求是错误的;您应该希望输出如中所示
my_column
在下面。为了以防万一,我在输出中同时包含了“我的”列和您请求的列;删除一个你不需要的,在你给我的意见适当考虑。