周数计算

nnt7mjpx  于 2021-07-26  发布在  Java
关注(0)|答案(5)|浏览(409)

表格:

Column1                 
2_2020
1_2020
52_2019

有没有办法将第1列(周数\年)中的前一周计算为第3列(前一周)
输出:

Column1       Column3           
 2_2020        1
 1_2020        52
 52_2019       (null)

第1列中的下划线分别分隔周数和年

ldioqlga

ldioqlga1#

如果你不关心几个世纪前历法的变化,那么你可以通过正则表达式得到数字

SELECT
  Column1, 
  DECODE(TO_NUMBER(REGEXP_SUBSTR(Column1, '^\d+')) - 1, 
         0, 52, 
         TO_NUMBER(REGEXP_SUBSTR(Column1, '^\d+')) - 1) as Column3
FROM Table
zlwx9yxi

zlwx9yxi2#

你可以用 lag() -但是您需要正确地拆分字符串并将部分转换为数字,以便可以使用它们对记录进行排序:

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
COLUMN1 | COLUMN3
:------ | :------
52_2019 | null   
1_2020  | 52_2019
2_2020  | 1_2020
qyzbxkaa

qyzbxkaa3#

这是一个糟糕的格式,因为它不保留顺序。我建议将其更改为yyyy\u ww——因此值将为2019\u 52、2020\u 01、2020\u 02。然后你可以简单地使用:

select lag(col) over (order by col)
from t;

如果没有这一点,什么是最好的方式,使之成为一种格式,保持秩序?不幸的是,甲骨文 to_date() 不允许输入周数。但它确实允许输入一年中的某一天,并保留了顺序。因此您可以使用:

select col,  lag(col) over (order by to_date(col, 'DDD_YYYY'))
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;
30byixjq

30byixjq4#

下面是一个sqlfiddle演示

SELECT X.WEEK_YEAR, X.NEXT_WEEK FROM (
SELECT A.WEEK_YEAR, A.WEEK, A.YEAR1, LEAD(A.WEEK) OVER(ORDER BY A.YEAR1 DESC, A.WEEK DESC) NEXT_WEEK FROM (
SELECT WEEK_YEAR, SUBSTR(WEEK_YEAR, 1, INSTR(WEEK_YEAR, '_')-1) WEEK, SUBSTR(WEEK_YEAR, INSTR(WEEK_YEAR, '_')+1) YEAR1 FROM TABLE1 ORDER BY 3 DESC, 2 DESC) A) X;
ecfdbz9o

ecfdbz9o5#

你可以利用最大周数(52或53)小于最大分钟数(59)的事实来使用黑客攻击。即使你的第一个数字代表周,为了这个查询,假装它代表分钟。然后可以使用不完整的日期格式模型('mi\u yyyy')在字符串和日期数据类型之间进行转换。oracle为其他组件提供默认值:当前月份 'mm' ,天 01 为了 'dd' ,小时 00 一小时,一秒 00 一秒钟。然后,您可以按这样构造的“日期”排序—无论第一个组件是“周数”还是“小时数”,顺序都是相同的。
如果oracle允许使用日期格式模型,这将简单得多 'iw_yyyy' ,但事实并非如此。
还要注意的是,由于我们希望按降序显示输出,所以我在分析函数中使用降序(因此,我必须使用 lead() 而不是 lag() ). 这避免了对行进行两次排序的需要(一次按升序排列用于分析函数,另一次按降序排列用于最终输出)。
正如我在你的问题下的评论中所说,我认为问题要求是错误的;您应该希望输出如中所示 my_column 在下面。为了以防万一,我在输出中同时包含了“我的”列和您请求的列;删除一个你不需要的,在你给我的意见适当考虑。

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

相关问题