【问题标题】:How to unify the datetime format when in Varchar在 Varchar 中如何统一日期时间格式
【发布时间】:2017-07-01 18:12:56
【问题描述】:

我想为给定数据库标准化我的日期时间。我需要能够使用日期进行统计。这是我到目前为止所做的:

select
 CASE PATINDEX('%[0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
    WHEN 1 then 'Pattern1'--CAST([Last Updated] AS Datetime) --2/8/2017 2:30:14 PM 
    ELSE
     CASE PATINDEX('%[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
        WHEN 1 then 'Pattern2' --2015-03-02 03:46:38 PM
        ELSE
        CASE PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
            WHEN 1 THEN 'Pattern3'
            ELSE
            CASE PATINDEX('%[0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                WHEN 1 THEN 'Pattern4'
                ELSE
                CASE PATINDEX('%[0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                    WHEN 1 THEN 'Pattern5'
                    ELSE
                    CASE PATINDEX('%[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                        WHEN 1 THEN 'Pattern6'
                        ELSE
                        CASE PATINDEX('%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] [0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                            WHEN 1 THEN 'Pattern7'
                            ELSE
                            CASE PATINDEX('%[0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                                WHEN 1 THEN 'Pattern8'
                                ELSE
                                CASE PATINDEX('%[0-9][0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                                    WHEN 1 THEN 'Pattern9'
                                    ELSE
                                    CASE PATINDEX('%[0-9][0-9]/[0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]%',[Last Updated])
                                        WHEN 1 THEN 'Pattern10'






END
    END
        END
            END
                END
                    END
                        END
                            END
                                END
                                    END
as 'Pattern'

当我尝试转换为日期时间时,它给了我一个错误...这里有一些例子:

Pattern1:
2/8/2017 8:06:56 AM 
2/2/2017 2:42:09 PM 
1/3/2017 9:10:20 AM  

Pattern 2:
2016-12-20 11:08:20 
2016-11-09 10:04:35 
2016-11-01 10:53:11 AM
2017-02-03 09:13:14 
2016-11-09 10:09:09 

Pattern3:
12/14/2016 11:54:53 AM
12/16/2016 11:05:24 AM
12/19/2016 12:23:51 PM

Pattern4:
8/15/2016 12:13:35 PM 
4/17/2015 12:29:54 PM 
2/22/2016 10:44:11 AM 
6/12/2014 10:08:07 AM 
9/16/2013 12:18:22 PM 

我希望它们都被标准化为格式:'02/13/2017 11:58:00'

有什么办法吗?

这是获取日期的方法:

WHEN (SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22))  = null THEN 'UNAVAILABLE' 
WHEN (SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22))  = '' THEN 'UNAVAILABLE'
WHEN (SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22))  like '%--%'
THEN 'UNAVAILABLE'

ELSE

    (Case  
    WHEN SUBSTRING(REVERSE((RTRIM(LTRIM((SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)))))),0,5) 
    --FOR AM
    LIKE '%MA%' THEN 
    SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)

    WHEN SUBSTRING(REVERSE((RTRIM(LTRIM((SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)))))),0,5)
    --FOR PM
    LIKE '%MP%' THEN
    SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)

    ELSE 

        (CASE
        WHEN LEN(RTRIM(LTRIM((SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22))))) <20
        THEN 'UNAVAILABLE'


        ELSE

            LEFT(RTRIM(LTRIM((SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)))),
            LEN(RTRIM(LTRIM((SUBSTRING(SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100),PATINDEX('%[0-9]%',SUBSTRING(Cast(Resolution as varchar(8000)),LEN(/**/Cast(Resolution as varchar(8000))/**/) - CHARINDEX('---------------------------------------------',REVERSE(/**/Cast(Resolution as varchar(8000))/**/)),100)),22)))))-2)


            END)

        END)

END)

as 'Last Updated'

这是来自日志系统。我不能真正提供太多信息,因为这些是机密信息。但是请注意,有很多人会将带有时间戳的 cmets 放在其 cmets 的末尾,其中包括他们的姓名和时间戳。通过那里的查询,我能够获得大部分日期。有时无法获取日期(日志中根本没有时间戳)。这是我可以举的例子:

Test Data
--------------------------------------------- 
FName LName 2/13/2017 1:19:42 PM

【问题讨论】:

  • 有一种非常简单的方法:将DATETIME 值存储为DATETIME 数据类型而不是VARCHAR。您不必担心在数据库中显示 DATETIME
  • 如果有这么多模式,实际上无法确定使用歧义样式的正确日期:02-03-2017 是 2 月 3 日还是 3 月 2 日?
  • 现在是 2017 年 2 月 13 日。但问题是我没有将其存储为日期时间,因为它在某些文本中...我手动获取大量文本中的日期
  • 你能提供一些你试图解析的文本数据的例子吗?
  • 我们需要不止一个例子。您可以编辑您的问题并添加 4 或 5 个不同的示例吗?

标签: sql sql-server sql-server-2008 tsql datetime


【解决方案1】:

我认为您的问题有一个更简单的解决方案。这是一个提议:

SELECT CONVERT(datetime, any_datetime_format) unified_datetime
from
(
    SELECT '2/8/2017 8:06:56 AM' any_datetime_format UNION
    SELECT '2/2/2017 2:42:09 PM' any_datetime_format UNION
    SELECT '1/3/2017 9:10:20 AM' any_datetime_format UNION
    SELECT '2016-12-20 11:08:20' any_datetime_format UNION
    SELECT '2016-11-09 10:04:35' any_datetime_format UNION
    SELECT '2016-11-01 10:53:11 AM' any_datetime_format UNION
    SELECT '2017-02-03 09:13:14' any_datetime_format UNION
    SELECT '2016-11-09 10:09:09' any_datetime_format UNION
    SELECT '12/14/2016 11:54:53 AM' any_datetime_format UNION
    SELECT '12/16/2016 11:05:24 AM' any_datetime_format UNION
    SELECT '12/19/2016 12:23:51 PM' any_datetime_format UNION
    SELECT '8/15/2016 12:13:35 PM' any_datetime_format UNION
    SELECT '4/17/2015 12:29:54 PM' any_datetime_format UNION
    SELECT '2/22/2016 10:44:11 AM' any_datetime_format UNION 
    SELECT '6/12/2014 10:08:07 AM' any_datetime_format UNION 
    SELECT '9/16/2013 12:18:22 PM' any_datetime_format
) t

如果格式不合适,并且您确实需要类似 '2/13/2017 1:19:42 PM' 的内容,您可以将 'CONVERT(datetime, any_datetime_format)' 替换为 'FORMAT(convert(datetime, any_datetime_format), 'MM/dd/yyyy HH:mm:ss tt')'

【讨论】:

  • 我只是在一个临时表中添加了日期,并且能够这样做。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 2013-03-02
  • 2021-04-17
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多