Oracle 推迟到下个月

Oracle 推迟到下个月,oracle,oracle12c,Oracle,Oracle12c,如果我提出疑问: TABLE: HIST CUSTOMER MONTH PLAN 1 1 A 1 2 B 1 2 C 1 3 D 我得到: select h.*, lead(plan) over (partition by customer order by month) np from HIST h 但是我想要 CUSTOMER MONTH PLAN

如果我提出疑问:

TABLE: HIST
CUSTOMER   MONTH   PLAN
1          1       A
1          2       B
1          2       C
1          3       D
我得到:

select h.*, lead(plan) over (partition by customer order by month) np from HIST h
但是我想要

CUSTOMER   MONTH   PLAN   np
1          1       A      B
1          2       B      C
1          2       C      D
1          3       D      (null)
原因是,下个月到2是3,加上D。我猜按客户订单按月进行分区并不像我想的那样有效


在Oracle 12c中有没有实现这一点的方法?

一种方法是使用范围分区和最小分析函数。像这样:

CUSTOMER   MONTH   PLAN   np
1          1       A      B
1          2       B      D
1          2       C      D
1          3       D      (null)
当您使用范围分区时,您告诉Oracle根据您所排序的列的值来创建窗口,而不是根据行来创建窗口

因此,例如

+----------+-------+------+----+
| CUSTOMER | MONTH | PLAN | NP |
+----------+-------+------+----+
|        1 |     1 | A    | B  |
|        1 |     2 | B    | D  |
|        1 |     2 | C    | D  |
|        1 |     3 | D    |    |
+----------+-------+------+----+
。。。将创建一个包含下一行的窗口

ROWS BETWEEN 1 following and 1 following
。。。将创建一个窗口,其中包含具有下一个月值的所有行

使现代化 如果可能会跳过给定客户的某些月份值,则可以使用以下变量:

RANGE BETWEEN 1 following and 1 following
您可以使用滞后/超前两次。第一次检查重复月份并在这些月份中将值设置为NULL,第二次使用IGNORE NULLS获取下一个月值

它还有一个额外的好处,即如果跳过几个月,它仍然会找到下一个值

Oracle 11g R2架构设置:

问题1:

:


为了使它在此处作为Oracle 12c以后的选项列出,您可以使用应用运算符来解决这种类型的问题

| CUSTOMER | MONTH | PLAN |     NP |
|----------|-------|------|--------|
|        1 |     1 |    A |      B |
|        1 |     2 |    B |      D |
|        1 |     2 |    C |      D |
|        1 |     3 |    D | (null) |
|        2 |     1 |    E |      G |
|        2 |     1 |    F |      G |
|        2 |     3 |    G |      H |
|        2 |     5 |    H | (null) |
我不知道有任何Oracle 12c公共小提琴,因此,SQL Server中的一个示例可以在这里找到:


评论我自己的答案。第一个_值不应该是确定的。我想我必须对行进行预排序,以保证在第一行中得到B而不是C。但我无法将其发送到第一行中的每个返回C,即使我对行进行预排序,以便C排在第一位。有什么评论吗?适用于Oracle-您也可以使用页面左上角的下拉列表更改数据库。@谢谢,但它不是Oracle 12c,也不是rextester或dbfiddle,apply运算符在11g中不可用。它是Oracle自己的服务,正在运行Oracle 18c。但你确实需要注册一个account@MTO再次感谢。是的,我知道这项服务,但我试图提供一个不在任何登录后面的fiddle地址。到目前为止,我还没有意识到任何事情,我相信总有一天会发生,但遗憾的是,现在还没有。
select h.*, 
       first_value(plan) over 
          (partition by customer 
           order by month 
           range between 1 following and unbounded following) np 
from h 
+----------+-------+------+----+
| CUSTOMER | MONTH | PLAN | NP |
+----------+-------+------+----+
|        1 |     1 | A    | B  |
|        1 |     3 | B    | D  |
|        1 |     3 | C    | D  |
|        1 |     4 | D    |    |
+----------+-------+------+----+
CREATE TABLE HIST ( CUSTOMER, MONTH, PLAN ) AS
SELECT 1, 1, 'A' FROM DUAL UNION ALL
SELECT 1, 2, 'B' FROM DUAL UNION ALL
SELECT 1, 2, 'C' FROM DUAL UNION ALL
SELECT 1, 3, 'D' FROM DUAL UNION ALL
SELECT 2, 1, 'E' FROM DUAL UNION ALL
SELECT 2, 1, 'F' FROM DUAL UNION ALL
SELECT 2, 3, 'G' FROM DUAL UNION ALL
SELECT 2, 5, 'H' FROM DUAL;
SELECT CUSTOMER,
       MONTH,
       PLAN,
       LEAD( np ) IGNORE NULLS OVER ( PARTITION BY CUSTOMER ORDER BY MONTH, PLAN, ROWNUM ) AS np
FROM   (
  SELECT h.*,
         CASE MONTH
         WHEN LAG( MONTH ) OVER ( PARTITION BY CUSTOMER ORDER BY MONTH, PLAN, ROWNUM )
         THEN NULL
         ELSE PLAN
         END AS np
  FROM   hist h
)
| CUSTOMER | MONTH | PLAN |     NP |
|----------|-------|------|--------|
|        1 |     1 |    A |      B |
|        1 |     2 |    B |      D |
|        1 |     2 |    C |      D |
|        1 |     3 |    D | (null) |
|        2 |     1 |    E |      G |
|        2 |     1 |    F |      G |
|        2 |     3 |    G |      H |
|        2 |     5 |    H | (null) |
select
     h.customer, h.month, h.plan, oa.np
from hist h
outer apply (
  select
       h2.plan as np
  from hist h2
  where h.customer = h.customer
  and h2.month > h.month
  order by month
  fetch first 1 rows only
  ) oa
order by
     h.customer, h.month, h.plan
| customer | month | plan |     np |
|----------|-------|------|--------|
|        1 |     1 |    A |      C |
|        1 |     2 |    B |      D |
|        1 |     2 |    C |      D |
|        1 |     3 |    D | (null) |