【问题标题】:fill missing data Oracle填补缺失数据 Oracle
【发布时间】:2016-08-22 21:31:00
【问题描述】:

相信我,我已经尽力找到这个问题了。我有 MYSQL 和 SQLServer 解决方案,而不是 Oracle,也没有我需要的特定汇总。 由于我使用的 Oracle 版本中没有 Cross Apply,所以我遇到了障碍。

问题对你们中的许多人来说很简单。

对我来说,宇宙的起点是 13 个月。

我有一张桌子

CREATE TABLE TBLTESTAUM (
ORDER_NO NUMBER(10,0) NOT NULL ENABLE,
RECORD_DATE DATE,
Order_SEQUENCE NUMBER(5,0) NOT NULL ENABLE,
CLASS NUMBER(3,0));

INSERT INTO TBLTESTAUM VALUES (1234, '29-Aug-2015', 34, 459);
INSERT INTO TBLTESTAUM VALUES (1234, '20-Jun-2016', 35, 877);
INSERT INTO TBLTESTAUM VALUES (1234, '20-Jun-2016', 37, 877);
INSERT INTO TBLTESTAUM VALUES (1234, '02-Jul-2016', 39, 122);
INSERT INTO TBLTESTAUM VALUES (1234, '28-Jul-2016', 40, 122);
INSERT INTO TBLTESTAUM VALUES (1234, '31-Jul-2016', 41, 311);
INSERT INTO TBLTESTAUM VALUES (1234, '10-Aug-2016', 42, 311);
INSERT INTO TBLTESTAUM VALUES (1234, '18-Aug-2016', 44, 110);
INSERT INTO TBLTESTAUM VALUES (1234, '20-Aug-2016', 45, 110);

请注意:

  1. 2015 年 7 月 20 日在第一个插入中。
  2. Seq 字段可能有也可能没有每个值。它可能缺少一些。如果你想使用它。
  3. Not Nullable for Sequence 是可忽略的。

所以滚动 13 个月给了我 22/07/2015,截至今天。

我希望在每周的“CLASS”情况下将其分解,如果该周不存在任何内容,则为最后应用的 CLASS。如果没有最后一个实例,即它是第一个实例,则接下来应用 CLASS。直到 CLASS 改变。

输出为 -

Order Num   WeekDate    CLASS
123         27-Jul-15   459
123         3-Aug-15    459
123         10-Aug-15   459
123         17-Aug-15   459
123         24-Aug-15   459
123         31-Aug-15   459
123         7-Sep-15    459
Dates and Order Num to continue till next match in TBLTESTAUM is found
123         20-Jun-16   877
123         27-Jun-16   122
123         4-Jul-16    122
123         11-Jul-16   122
123         25-Jul-16   311
123         1-Aug-16    311
123         8-Aug-16    311
123         15-Aug-16   110
123         22-Aug-16   110

有多个订单号。但我希望你的代码适合所有。 请注意

它需要汇总到每周状态。
需要进行每月状态。但希望我能从你的代码中弄清楚这一点。

提前谢谢你。

PS:接下来的 10 小时内我将无法查看您的回复。男人要睡觉了。但非常感谢您花在这方面的任何时间。

【问题讨论】:

  • 同时向我们展示预期的结果,以及您之前使用过的查询。
  • 您认为为什么需要横向连接 (cross apply)?
  • @jarlh 我正在一块一块地做。由于某种原因,超链接格式错误。它给了我错误,说代码格式错误。
  • 问题...weekdate 总是星期一?或者它总是与“今天的日期”在一周中的同一天(如果我在星期四运行,是否都是 weekdate 的星期四?)然后 - 我确实没有通知 20/Jul /2015 在第一个插入中,你是什么意思?此外,您在输入中的订单号是 1234,但在输出中是 123 - 这是拼写错误吗?然后:我看到在星期一,课程是从星期一开始的那一周开始的,而不是从前一周开始的。这没关系,也很清楚。如果同一周有两行或多行怎么办 - 应该显示什么,该周的第一个或最后一个 CLASS?
  • @seewe - 是的,这应该是您需要触摸的唯一部分(如果您已经删除了最外面的 select 中的“-6”)。这也会容易得多 - 只需使用 trunc(add_months(sysdate, -(level - 1), 'mm')) 即可 - 一次让你回到一个月。不需要所有这些算术计算。

标签: sql oracle


【解决方案1】:

下面的查询可能会满足您的需求。如果没有,请说明与您的要求相比有何不同。 (请同时回答我在评论中对您的问题提出的问题)。

在此解决方案中,我生成所需的日期(首先作为星期日,因为您想捕获“当前周”期间发生的事情,然后在最终的外部查询中将它们更改为星期一)。我还从您提供的表格中生成了order_no,但在有意义的现实生活中,这是不必要的;您应该有一个与主键具有相同 order_no 的“订单”表,并且我的 CTE“o”应该从该表中提取订单号,而不是从tbltestaum

祝你好运!

with
     w ( weekdate ) as (
       select trunc(sysdate, 'iw') - 7 * (level - 1) + 6  -- This will generate Sundays
       from   dual
       connect by level <= 1 + 
                   ( trunc(sysdate, 'iw') - trunc(add_months(sysdate, -13), 'iw') ) / 7
     ), 
     o ( order_no ) as (
       select distinct order_no from tbltestaum
     ),
     prep ( order_no, dt, order_sequence, class ) as (
       select order_no, record_date, order_sequence, class
         from tbltestaum
       union all
       select order_no, weekdate, null, null
         from w cross join o
     ),
     z ( order_no, dt, order_sequence, class ) as (
       select order_no, dt, order_sequence,
              nvl( last_value(class ignore nulls) over (partition by order_no 
                                                        order by dt, order_sequence),
                  first_value(class ignore nulls) over (partition by order_no
                                                        order by dt, order_sequence
                             rows between unbounded preceding and unbounded following ) )
       from   prep
     )
select order_no, to_char(dt - 6, 'dd-Mon-yy') as weekdate, class
from   z
where  order_sequence is null
;

【讨论】:

  • 这适用于我之前所说的要求。但正如我之前所说,这是下周一。我正在尝试更改您的查询以适应它。如果它不起作用,让我回来。但是,谢谢。
  • 好的,我会重写-希望它可以帮助将来可能有相同问题的其他SO成员。
  • 其实我不需要重写。需要进行以下小改动才能在星期一早上获取过去一周的更改(假设星期一发生的任何事情都只在该周结束时获取):从第三行代码中删除 +6,从代码中删除 -6从底部算起的第三行。然后在 last_value 和 first_value 的“order by”部分的 order_sequence 之后添加“nulls first”(在这两种情况下都在右括号之前)。如果您希望星期一发生的事情影响那个星期一,而不是下一个星期一,那就更简单了 - 只删除 +6 和 -6。
  • 真棒,就像一个魅力。非常感谢。我希望实践能让我像你一样思考。天才。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-11
  • 2018-08-14
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多