SQL ORACLE从多个日期时间行获取周数

SQL ORACLE从多个日期时间行获取周数,sql,oracle,date,datetime,Sql,Oracle,Date,Datetime,我有70.000行数据,包括日期时间列YYYY-MM-DD HH24-MM-SS。。 我想把这些数据分成3列;小时、日和周数 日期时间列名是“CONTRACTS”表中的“REGISTRATIONDATE” 这是我到目前为止在day和hour专栏中看到的内容: SELECT substr(REGISTRATIONDATE, 0, 10) AS "Date", substr(REGISTRATIONDATE, 11, 9) AS "Hour" FROM CONTRACTS; 我已经看到了为特定日期

我有70.000行数据,包括日期时间列YYYY-MM-DD HH24-MM-SS。。 我想把这些数据分成3列;小时、日和周数

日期时间列名是“CONTRACTS”表中的“REGISTRATIONDATE”

这是我到目前为止在day和hour专栏中看到的内容:

SELECT substr(REGISTRATIONDATE, 0, 10) AS "Date",
substr(REGISTRATIONDATE, 11, 9) AS "Hour"
FROM CONTRACTS;

我已经看到了为特定日期获取周数的选项,此任务涉及70.000个日期,因此这不是一个选项。

假设您的注册日期格式为“MM/DD/YYYY”

更简单、更快的查询是基于ond to_charto_dateREGISTRATIONDATE、'MM/DD/YYYY'、'WW' 否则,请在适当的日期转换列,并执行周数转换

SELECT substr(REGISTRATIONDATE, 0, 10) AS "Date",
substr(REGISTRATIONDATE, 11, 9) AS "Hour",
to_char(to_date(REGISTRATIONDATE,'MM/DD/YYYY'),'WW') as "Week"
FROM CONTRACTS;

这很混乱,但它看起来很有效:

to_char(
        to_date(RegistrationDate,'YYYY-MM-DD HH24-MI-SS') + 
        to_number(to_char(trunc(to_date(RegistrationDate,'YYYY-MM-DD HH24-MI-SS'),'YEAR'),'D'))
        - 2,
        'WW')
在外部,您有其他人提供的解决方案,但使用正确的日期格式。在中间,有一定的天数的调整,以适应1月1日落下的地方。trunc部分从日期获得1月1日,D部分获得1月1日的工作日。因为1代表周日,我们必须使用-2来获得我们需要的

编辑:稍后我可能会删除这个答案,但在我看来@mathguy的答案是最好的。关于如何扩展到一般解决方案,请参见关于该答案的评论

但首先你需要:

在1月的第一个星期一之前决定要做什么,以及 解决日期中阻止转换为日期的根本问题。 关于第1点,如果不接受第0周的分配,您希望第52/53周的分配会变得更复杂,但我们仍然能够提供帮助

正如我所看到的,在第2点上,要么是系统性的错误,也许是时间戳,包含了几分之一秒,要么是孤立的无效数据


不计算长度、格式或特定值。您收到的错误消息表明,至少有一些数据太长,我的评论中的代码应该可以帮助您找到这些数据。

在一年的第一个星期一之前,OP仍然需要解释为一年中的前几天分配的周数。您是否为上一日历年指定了周数?在一篇关于2017年1月1日的评论中,我问了一个例子;那是一个星期天。根据您的定义,2017年1月2日至1月8日的一周为第一周;您分配给2017年1月1日星期日的周数是多少

下面的简单计算为其分配了第0周。除此之外,计算非常简单

注意:要查找任何给定日期dt的一周星期一,我们可以使用truncdt“iw”。iw代表ISO周,标准周从周一开始,周日结束

然后:为了找到一年中的第一个星期一,我们可以从1月7日开始,并询问1月7日所在周的星期一。我不会解释这一点——这是简单的逻辑,与编程无关

要输入固定日期,最好使用日期文字语法:1月7日的日期“2017-01-07”。如果您不熟悉Oracle文档中的日期文字,请查看该文档

所以:要找到任何日期dt的周数,请计算

这个公式找到dt的ISO周的星期一,然后减去一年中的第一个星期一——使用Oracle日期算法,其中两个日期之间的差值是它们之间的天数。我们除以7得到周数;要让第一个星期一被分配数字1,而不是0,我们需要在除以7的结果上加1


您必须解决的另一个问题是将字符串转换为日期。最好的解决方案是修复数据模型本身,更改列的数据类型,使其为DATE而不是VARCHAR2;然后,您需要的所有数据位都可以更容易地提取出来,您可以确保当前数据中没有“2017-02-29 12:30:00”这样的日期,如果有,您将很难进行任何日期计算,查询速度将大大加快,等等,这是一个完全不同的问题,因此我将把它排除在讨论之外。

对于日期的周数没有标准定义。你这是什么意思?甲骨文有自己的理解,不过。。。如果你想要的是一个好的答案,那么已经提供了一个很好的答案。可能是“周数”的重复,我的意思是一年有52周,我希望有一列记录适合日期的周数,例如今天2017/06/03是第22周。提供的答案可能足够了,但也要检查我链接的可能重复项。这在很大程度上取决于你如何定义第一周。它是从1月1日开始的,还是1月的第一个星期一或其他什么时候开始的。。。尝试各种不同的选择,如果没有一个有效,那么回来更准确地说明你的需求。我已经尝试了大约20种不同的选择如何做到这一点
我正在学习SQL,每次我得到的选项都适用于需要特定日期的周数的情况。我有70000个约会,所以这可能不方便。我所说的“周数”是指第一周从1月的第一个星期一开始。此时我已经有了“小时”和“天”栏。我想创建一行代码,让我有第三行的周数,适合日期。我希望这能让它更准确。当我尝试记录dateREGISTRATIONDATE,'MM/DD/YYYY','WW'作为一周时,我得到错误ORA-01830:日期格式图片在转换整个输入字符串之前结束这取决于注册日期中的格式。。。在我的回答中,我假设您的格式为“MM/DD/YYYY”。。。但是我不知道你的真实格式如果你的字段是日期时间,那么你只需要输入日期时间,'WW'我的字段实际上是日期时间,当我仅使用to_charREGISTRATIONDATE'WW'尝试时,不幸的是,我得到了错误ORA-1722:无效数字。请尝试将时间部分删除为to_CHARREGISTRATION,'DD/MM/YYYY',“DD/MM/YYYY”…只要你有机会,一定要让我知道这是怎么回事。如果结果不太正确,我相信我们能解决它。或者,如果它符合您的需要,请通过感谢的方式将我的答案标记为“已接受”,并帮助其他用户找到最有用的信息。谢谢您的帮助。我尝试了这个答案,但得到了错误ORA-01830:日期格式图片在转换整个输入字符串之前结束。我认为这意味着您的数据,或至少一行数据,没有格式为“YY-MM-DD HH24-MI-SS”的字段。如果数据看起来大多是正确的格式,您可能希望从合同中运行select*,其中lengthREGISTRATIONDATElength'YYYY-MM-DD HH24-MI-SS';根据数据问题的不同,另一种选择可能是用to_datesubstrRegistrationDate,1,10,'YYYY-MM-DD HH24-MI-SS'替换to_dateRegistrationDate的两个实例,即to_datesubstrRegistrationDate,1,10,'YYYY-MM-DD'!我会删除我的答案,除了关于查找不良数据的建议可能仍然有用+1在此基础上,如果没有更改表的选项,因此REGISTRATIONDATE实际上是一个datetime字段,如果您对数据问题进行排序,并乐意在1月的第一个星期一之前为1月的日期指定第0周,则您需要的代码是:1+truncto_dateREGISTRATIONDATE,'YYYY-MM-DD HH24-MI-SS',“iw”-truncto_DateSubstrertRegistrationDate,1,4 | |'-01-07',“YYYY-MM-DD”,“iw'/7@SteveLovell-使用to_date而不是date literal的优点;如果OP有不同年份的日期,则应根据每个日期的具体年份进行计算;日期文字只是一个文字,它不能使用表达式,表达式的值是年份。
1 + ( trunc(dt, 'iw') - trunc(date '2017-01-07', 'iw') ) / 7