根据日期重置计数器值
Posted
技术标签:
【中文标题】根据日期重置计数器值【英文标题】:Reseting Counter Value based on Date 【发布时间】:2020-06-04 23:04:06 【问题描述】:在查询 Oracle 数据库时,我正在构建一个表,用于计算从 issue_date 开始存在的每一年的许可证年龄。比如:
LICENSE_NUMBER ISSUE_ANNIVERSARY LICENSE_AGE
1234 13-JUN-83 1
1234 13-JUN-84 2
1234 13-Jun-85 3
1234 13-Jun-86 4
1234 13-Jun-87 5
1234 13-Jun-88 6
1234 13-Jun-89 7
我得到了一个警告。当 ISSUE_ANNIVERSARY 到 1986 年时,我必须将年龄重新设置为 1。所以,我想要的结果如下所示:
LICENSE_NUMBER ISSUE_ANNIVERSARY LICENSE_AGE
1234 13-JUN-83 1
1234 13-JUN-84 2
1234 13-Jun-85 3
1234 13-Jun-86 1
1234 13-Jun-87 2
1234 13-Jun-88 3
1234 13-Jun-89 4
我的方法是设置条件 CASE 子句以在 ISSUE_ANNIVERSARY 包含 1986 年时重置 LICENSE_AGE 但是我认为我的语法不正确。我尝试了几种方法,但不断出错。我的最新尝试如下。我并没有挂断这种 CASE 方法,但是我必须记住,我在 1986 年之前、1986 年期间和 1986 年之后都颁发了许可证,所以我认为一个条件最好。感谢您提出任何建议!
WITH LICENSE (license_number, issue_anniversary, expiry_date, license_age) AS
(
SELECT lic.license_number, lic.issue_date, lic.expiry_date, 1
FROM license_table lic
UNION ALL
SELECT license_number, ADD_MONTHS(issue_anniversary, 12), expiry_date,
CASE
WHEN EXTRACT(YEAR FROM ADD_MONTHS(issue_anniversary, 12) = 1986 THEN 1
ELSE
license_age + 1
END
FROM license
WHERE expiry_date <= sysdate and license_number = 1234
)
SELECT license_number,
issue_anniversary,
license_age
FROM license
【问题讨论】:
是什么让您认为您的方法不正确? (1) 同时存储日期和年龄违反了第三范式,如果它们不同步,就有丢失 R/I 的风险。考虑只存储日期。您可以将年龄包含在计算列中,也可以改用视图。 (2) 您是否考虑过 License_Year 表?然后,您可以加入它以确定如何计算年龄。否则,您将无法将 1986 硬编码到您的代码中。 @JohnWu:(1) 他们没有存储它,而是在递归查询中动态计算它。 @GMB。好问题。从理论上讲,我觉得方法是正确的。至少,如果我从我的 python 背景中绘制,我就在正确的范围内,但是我会遇到各种不同的错误,这取决于我尝试的方法,所以我觉得我需要问一下。另外,感谢您的澄清。是的,我想计算字段,而不是存储它。 @Mike:乍一看,您的代码对我来说看起来不错。您应该对其进行测试,并告知您是否有一些具体问题。 【参考方案1】:你可以使用row_number()
:
select t.*,
row_number() over (partition by license_number,
case when ISSUE_ANNIVERSARY < date '1986-01-01' then 1 else 0 end
order by ISSUE_ANNIVERSARY
) as license_age
from license_table lt;
【讨论】:
@George Linoff。谢谢你的建议。我之前没有使用过 OVER 子句和分区,我一直在玩一些使用它的代码。虽然我解决了自己的问题,但我肯定学到了一些有用的东西,我相信我可以使用你的逻辑。感谢您的贡献!以上是关于根据日期重置计数器值的主要内容,如果未能解决你的问题,请参考以下文章
如何在重置之前向日志添加值(CoreData 和 Swift)
根据参数 -Oracle 重新启动 sum(over) 函数
在 pyspark 中,基于变量字段进行分组,并为特定值添加一个计数器(当变量更改时重置)