在SQL中将日期INT转换为日期

在SQL中将日期INT转换为日期,sql,oracle,date,where-clause,Sql,Oracle,Date,Where Clause,如何将日期整数转换为日期类型?20200531年至2020年5月31日 我的当前表的数据日期格式为YYYYMMDD 20200531、20200430等 根据我使用的Toad数据点软件,datadate的数据类型是int。我相信它使用的是ORACLE sql数据库 因此,在查询此数据时,我必须按如下方式键入where子句 where datadate = '20200531' 我的目标是将这个整数datadate转换为日期格式5/31/2020,以便将datadate应用于where子句 像

如何将日期整数转换为日期类型?20200531年至2020年5月31日

我的当前表的数据日期格式为YYYYMMDD 20200531、20200430等

根据我使用的Toad数据点软件,datadate的数据类型是int。我相信它使用的是ORACLE sql数据库

因此,在查询此数据时,我必须按如下方式键入where子句

where datadate = '20200531'
我的目标是将这个整数datadate转换为日期格式5/31/2020,以便将datadate应用于where子句

WHERE datadate = dateadd(DD, -1, CAST(getdate() as date))

如果是int列,请阅读下面我的答案

假设它是一个文本字符串: 假设datadate是字符串、文本等列,而不是date/datetime/datetime2/datetimeoffset列,则使用样式为23的转换函数。23值对应于ISO 8601,因为这些值按yyyy-MM-dd顺序排列,即使它们缺少破折号

本页有样式编号的参考:

假设它是一个实际的int列: 快速而肮脏的方法是将int转换为varchar,然后使用与上面相同的代码,就像它是一个文本字段一样-但不要这样做,因为这样做很慢:

SELECT
    *
FROM
    (
        SELECT
            myTable.*,
            CONVERT( char(8), datadate ) AS valueAsChar,
            CONVERT( date, CONVERT( char(8), datadate ), 23 ) AS valueAsDate
        FROM
            myTable
    ) AS q
WHERE
    q.valueAsDate = DATEADD( dd, -1, GETDATE() )
假设它是一个实际的int列,更好的答案是: 我们需要使用DATEFROMPARTS,并使用Base-10算法提取每个组件

如果我们有一个表示格式化日期的整数,例如20200531,那么:

我们可以通过执行MOD 31来获得日期,例如19950707 MOD 31==7 我们可以先除以100,去掉日部分,然后取12模:例如20200531/100==202005,202005 MOD 12==5 我们可以通过除以10000得到年份,例如20200531/10000==2020。 顺便说一句:

SQL Server使用%作为模运算符,而不是MOD。 整数除法会导致截断,而不是产生十进制或浮点值,例如5/2==2而不是2.5。 像这样:

SELECT
    q2.* 
FROM
    (
        SELECT
            q.*,
            DATEFROMPARTS( q.[Year], q.MonthOfYear, q.DayOfMonth ) AS valueAsDate
        FROM
            (
                SELECT
                    myTable.*,

                    ( datadate % 31 ) AS DayOfMonth,
                    ( ( datadate / 100 ) % 12 ) AS MonthOfYear,
                   ( datadate / 10000 ) AS [Year]
                FROM
                    myTable
            ) AS q
    ) AS q2
WHERE
    q2.valueAsDate = DATEADD( dd, -1, GETDATE() )
显然,使用SQL时有两个嵌套的子查询是一件痛苦的事情,它有着糟糕的人体工程学,我不明白SQL如何或为什么不允许SELECT子句中的表达式被同一查询中的其他表达式使用-这真的是一种糟糕的人体工程学…-但我们可以将其转换为标量UDF,因此不会影响性能

此函数中有一个TRY/CATCH块,因为您可能会处理一个无效值,如20209900,它不是实际日期,因为2020年没有第99个月的第0天。在这种情况下,函数返回NULL

我们可以在这样的查询中使用:

SELECT
    myTable.*,
    dbo.convertHorribleIntegerDate( datadate ) AS valueAsDate
FROM
    myTable
由于SELECT无法与同一查询中的其他表达式共享表达式结果,因此您仍需要使用外部查询来处理valueAsDate或重复dbo.ConvertTorbleIntegerDate函数调用:

SELECT
    *
FROM
    (
        SELECT
            myTable.*,
            dbo.convertHorribleIntegerDate( datadate ) AS valueAsDate
        FROM
            myTable
    ) AS q
WHERE
    q.valueAsDate = DATEADD( dd, -1, GETDATE() )

如果是int列,请阅读下面我的答案

假设它是一个文本字符串: 假设datadate是字符串、文本等列,而不是date/datetime/datetime2/datetimeoffset列,则使用样式为23的转换函数。23值对应于ISO 8601,因为这些值按yyyy-MM-dd顺序排列,即使它们缺少破折号

本页有样式编号的参考:

假设它是一个实际的int列: 快速而肮脏的方法是将int转换为varchar,然后使用与上面相同的代码,就像它是一个文本字段一样-但不要这样做,因为这样做很慢:

SELECT
    *
FROM
    (
        SELECT
            myTable.*,
            CONVERT( char(8), datadate ) AS valueAsChar,
            CONVERT( date, CONVERT( char(8), datadate ), 23 ) AS valueAsDate
        FROM
            myTable
    ) AS q
WHERE
    q.valueAsDate = DATEADD( dd, -1, GETDATE() )
假设它是一个实际的int列,更好的答案是: 我们需要使用DATEFROMPARTS,并使用Base-10算法提取每个组件

如果我们有一个表示格式化日期的整数,例如20200531,那么:

我们可以通过执行MOD 31来获得日期,例如19950707 MOD 31==7 我们可以先除以100,去掉日部分,然后取12模:例如20200531/100==202005,202005 MOD 12==5 我们可以通过除以10000得到年份,例如20200531/10000==2020。 顺便说一句:

SQL Server使用%作为模运算符,而不是MOD。 整数除法会导致截断,而不是产生十进制或浮点值,例如5/2==2而不是2.5。 像这样:

SELECT
    q2.* 
FROM
    (
        SELECT
            q.*,
            DATEFROMPARTS( q.[Year], q.MonthOfYear, q.DayOfMonth ) AS valueAsDate
        FROM
            (
                SELECT
                    myTable.*,

                    ( datadate % 31 ) AS DayOfMonth,
                    ( ( datadate / 100 ) % 12 ) AS MonthOfYear,
                   ( datadate / 10000 ) AS [Year]
                FROM
                    myTable
            ) AS q
    ) AS q2
WHERE
    q2.valueAsDate = DATEADD( dd, -1, GETDATE() )
显然,使用SQL时有两个嵌套的子查询是一件痛苦的事情,它有着糟糕的人体工程学,我不明白SQL如何或为什么不允许SELECT子句中的表达式被同一查询中的其他表达式使用-这真的是一种糟糕的人体工程学…-但我们可以将其转换为标量UDF,因此不会影响性能

此函数中有一个TRY/CATCH块,因为您可能会处理一个无效值,如20209900,它不是实际日期,因为2020年没有第99个月的第0天。在这种情况下,函数返回NULL

我们可以在这样的查询中使用:

SELECT
    myTable.*,
    dbo.convertHorribleIntegerDate( datadate ) AS valueAsDate
FROM
    myTable
由于SELECT无法与同一查询中的其他表达式共享表达式结果,因此您仍需要使用外部查询来处理valueAsDate或重复dbo.ConvertTorbleIntegerDate函数调用:

SELECT
    *
FROM
    (
        SELECT
            myTable.*,
            dbo.convertHorribleIntegerDate( datadate ) AS valueAsDate
        FROM
            myTable
    ) AS q
WHERE
    q.valueAsDate = DATEADD( dd, -1, GETDATE() )
这是假设的答案 正如您在问题中所建议的那样,您目前正在运行Oracle

如何将日期整数转换为日期类型?20200531年至2020年5月31日

在Oracle中,可以使用to_date将字符串转换为数字。如果您给它一个数字,它会在转换之前隐式地将其转换为字符串。因此,在这两种情况下,您都会:

to_date(datadate, 'yyyymmdd')
我的目标是将这个整数datadate转换为日期格式5/31/2020,以便将datadate应用于where子句

通常,您希望避免在where谓词中的列上应用函数:这是无效的,因为数据库需要在能够进行筛选之前对整个列应用函数。如果您想在dateadd上筛选截止到昨天的日期,那么我建议您计算昨天的日期,并将其与筛选的列的格式相同,这样您就可以直接匹配现有的列值

如果列是字符串:

where datadatea = to_char(sysdate - 1, 'yyyymmdd')
如果是一个数字:

where datadatea = to_number(to_char(sysdate - 1, 'yyyymmdd'))

这个答案假设您正在运行Oracle,正如您在问题中所建议的那样

如何将日期整数转换为日期类型?20200531年至2020年5月31日

在Oracle中,可以使用to_date将字符串转换为数字。如果您给它一个数字,它会在转换之前隐式地将其转换为字符串。因此,在这两种情况下,您都会:

to_date(datadate, 'yyyymmdd')
我的目标是将这个整数datadate转换为日期格式5/31/2020,以便将datadate应用于where子句

通常,您希望避免在where谓词中的列上应用函数:这是无效的,因为数据库需要在能够进行筛选之前对整个列应用函数。如果您想在dateadd上筛选截止到昨天的日期,那么我建议您计算昨天的日期,并将其与筛选的列的格式相同,这样您就可以直接匹配现有的列值

如果列是字符串:

where datadatea = to_char(sysdate - 1, 'yyyymmdd')
如果是一个数字:

where datadatea = to_number(to_char(sysdate - 1, 'yyyymmdd'))

指定哪个sql?当你说“数据集”时,你是指sql表吗?告诉我们datadate类型。日期整数不是您认为的那样。您有一个字符串格式的日期。实际整数日期将是UNIX时间戳值。请确认datadate列的确切数据类型而不是日期类型。它真的是一个char/varchar/nchar/nvarchar列吗?两个观察结果:首先,您的声明我相信它使用的是ORACLE sql数据库。我的。您必须知道您正在处理的是什么数据库,因为任何和所有可能的解决方案都依赖于此。其次,同样重要的是准确地知道列的数据类型。如果它在oracle中不是DATE,或者在其他数据库中是等效的,那么您有一个非常严重的设计缺陷。指定哪个sql?当您说“dataset”时,您是指sql表吗?告诉我们datadate类型。日期整数不是您认为的那样。您有一个字符串格式的日期。实际整数日期将是UNIX时间戳值。请确认datadate列的确切数据类型而不是日期类型。它真的是一个char/varchar/nchar/nvarchar列吗?两个观察结果:首先,您的声明我相信它使用的是ORACLE sql数据库。我的。您必须知道您正在处理的是什么数据库,因为任何和所有可能的解决方案都依赖于此。其次,同样重要的是准确地知道列的数据类型。如果它在oracle中不是DATE,或者在其他数据库中是等效的,那么您就有一个非常严重的设计缺陷。