【发布时间】:2016-06-29 00:55:10
【问题描述】:
我需要分析存储在一个 Oracle 数据库表中的一段数据。此表中的示例行如下所示:
Department Date Status
------------------------------------
D1 2016/6/1 1
D1 2016/5/31 0
D1 2016/5/30 0
D1 2016/5/29 1
D1 2016/5/28 0
D1 2016/5/27 1
D2 2016/6/1 0
D2 2016/5/31 1
D2 2016/5/30 1
D2 2016/5/29 0
D2 2016/5/28 0
D2 2016/5/27 1
每个部门和每个日期都有一行。我想要的是,对于任何给定日期的每个部门,找到Status 在此日期之前为 0 的第一个日期。例如,对于部门 D1,对于 2016/6/1,结果是 2015/5/30,对于 D1、2016/5/31 和 5/30,结果也是 2015/5/30。对于 D1,2016/5/29 和 5/28,它是 2016/5/28。
我需要将结果输出为SELECT 结果并将其存储在另一个表中。因此结果表的行数与原始表完全相同。结果表中大概有三列:Department、Date、TargetDate。
我对 SQL / PL SQL 的经验很少。我想我应该使用分析函数和窗口,但我真的无法提出查询。请给我一些建议。谢谢!
【问题讨论】:
-
分析功能是正确的(和窗口),但首先请澄清要求。 D2 和 2016/5/27 的预期结果是什么?也就是说,如果一个部门的最旧行的状态为 1(或更一般地说,不为零)怎么办? ....实际上等等,你说当状态为 0 但在你的例子中 D1 和日期 5/29 和 5/28 你说结果应该是 5/27,但 5/27 的状态是 1,而不是 0 。 请说清楚。 (最好通过编辑您的帖子,而不是在 cmets 中。)
-
@mathguy 感谢您的评论。 1) 如果最旧的行的状态为 1,或者与零不同,则
TargetDate应该为空,这意味着我们找不到该日期之前状态为 0 的任何日期。2) 抱歉。对于 D1 和 5/29、5/28,结果应该是 2016/5/28。那是一个错字。我已经在原帖中更正了。 -
酷,谢谢。再问一个问题,以确保我理解要求。似乎对于每个日期,您都会转到状态为零的最近日期(如果状态为零,则可能是日期本身,或者返回历史记录直到找到第一个零)。然后不要选择状态为零的最新日期;相反,如果它是状态为零的连续日期序列的一部分,请从该连续序列中选择最旧的日期。这就是为什么 6/1、5/31 和 5/30 的答案是 D1 部门的 5/30。正确的?如果是这样,这就是所谓的“tabibitosan”方法的应用。
-
您理解的@mathguy 是绝对正确的(查找状态全部为0的连续日期块的第一个/最旧日期。并且该块本身已关闭并且在给定日期之前。状态在给定的日期可以是 1 或 0) 。由于您已经清楚地命名了该方法(并且我在 Oracle 社区上找到了该文章),因此我将尝试自己理解这一点。如果我仍然无法弄清楚,我会回到你身边。非常感谢!
-
我错了; tabibitosan 方法在这种情况下无济于事,但分析函数
lag()会(除了我想到的其他任何东西)。在下面发布它作为答案。
标签: oracle plsql data-analysis