使用oracle sql查找天数更新

时间:2015-05-07 16:44:37

标签: sql oracle

我有一个表t1,表格结构如下:

Period_xi yearmonth
1          2021/01
2          2021/02

period_Xi是表t1的主键。我将创建第二个表t2,如下所示:

period_xi yearmonth  CM-1   CM-2 CM-3 CM-4 CM-5 CM-6 CM-7 CM-8 CM-9 CM-10 CM-11 CM-2
1          2021/01    31    30    31   
2          2021/02

我必须将列CM-1更新为31,将CM-2更新为30天,以查找上个月的天数。

尝试在单个SQL中查找更新SQL以更新最近12个月(天数)

是否可以这样做

感谢您的帮助......

1 个答案:

答案 0 :(得分:0)

您可以使用分层查询根据yearmonth所代表的日期查找前12个月;为了简洁,这发现了最后三个月:

select period_xi, yearmonth, level as offset,
  extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -level))) as days
from t1
connect by level <= 3
and prior period_xi = period_xi
and prior dbms_random.value is not null;

PERIOD_XI YEARMONTH OFFSET DAYS
--------- --------- ------ ----
        1 2021/01        1   31
        1 2021/01        2   30
        1 2021/01        3   31
        2 2021/02        1   31
        2 2021/02        2   31
        2 2021/02        3   30
...

然后,您可以将结果转换为多个列(假设您使用11g或更高版本):

select * from (
  select period_xi, yearmonth, level as offset,
    extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -level))) as days
  from t1
  connect by level <= 12
  and prior period_xi = period_xi
  and prior dbms_random.value is not null
)
pivot (max(days) for (offset) in (1 as "CM-01", 2 as "CM-02", 3 as "CM-03",
  4 as "CM-04", 5 as "CM-05", 6 as "CM-06", 7 as "CM-07", 8 as "CM-08",
  9 as "CM-09", 10 as "CM-10", 11 as "CM-11", 12 as "CM-12"));

PERIOD_XI YEARMONTH CM-01 CM-02 CM-03 CM-04 CM-05 CM-06 CM-07 CM-08 CM-09 CM-10 CM-11 CM-12
--------- --------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
        2 2021/02      31    31    30    31    30    31    31    30    31    30    31    29
        1 2021/01      31    30    31    30    31    31    30    31    30    31    29    31
        3 2021/03      28    31    31    30    31    30    31    31    30    31    30    31
...

您可以使用它插入新表,或作为更新或合并的一部分。虽然创建视图可能更简单,而不是存储重复数据。

你也可以使用11g的虚拟列:

create table t2 (period_xi number, yearmonth varchar2(7),
  cm_01 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -1)))),
  cm_02 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -2)))),
  cm_03 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -3)))),
  cm_04 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -4)))),
  cm_05 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -5)))),
  cm_06 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -6)))),
  cm_07 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -7)))),
  cm_08 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -8)))),
  cm_09 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -9)))),
  cm_10 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -10)))),
  cm_11 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -11)))),
  cm_12 number generated always as (extract(day from last_day(add_months(to_date(yearmonth, 'YYYY/MM/'), -12))))
);

insert into t2 (period_xi, yearmonth) values (1, '2021/01');
insert into t2 (period_xi, yearmonth) values (2, '2021/02');
insert into t2 (period_xi, yearmonth) values (3, '2021/03');

select * from t2;

PERIOD_XI YEARMONTH CM_01 CM_02 CM_03 CM_04 CM_05 CM_06 CM_07 CM_08 CM_09 CM_10 CM_11 CM_12
--------- --------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
        1 2021/01      31    30    31    30    31    31    30    31    30    31    29    31
        2 2021/02      31    31    30    31    30    31    31    30    31    30    31    29
        3 2021/03      28    31    31    30    31    30    31    31    30    31    30    31