【问题标题】:How to convert text to date entered as a date in sql?如何将文本转换为在sql中作为日期输入的日期?
【发布时间】:2019-06-20 13:34:08
【问题描述】:

数据类型为 TEXT 并输入为“20/11/2017”,使用 MAX 或 MIN 时会忽略月份。我正在尝试将其转换为月份的日期格式以供考虑。

CAST AND CONVERT 似乎不起作用,因为以下错误返回

消息 241,第 16 级,状态 1,第 13 行
从字符串转换日期和/或时间时转换失败。

代码:

SELECT     
    user_id, 
    record_id
    --CAST(onSale AS date) AS onSale
    --CONVERT(DATE, onSale) AS onSale, 
    --CONVERT(DATE, OffSale) AS OffSale
FROM (SELECT  user_id, 
             record_id,
             (SELECT MAX(value) AS Expr1
             FROM      UPLOADS.LINES AS SUH WITH (NoLock, ReadUncommitted)
             WHERE  (field_id = 4782) AND (record_id = UR.record_id)) AS onSale,
             (SELECT MAX(value) AS Expr1
             FROM      UPLOADS.LINES AS SUH WITH (NoLock, ReadUncommitted)
             WHERE  (field_id = 4783) AND (record_id = UR.record_id)) AS OffSale
        FROM   UPLOADS.RECORDS AS UR WITH (NoLock, ReadUncommitted)
        WHERE      (module_id = 18)) AS DATA;

最终结果基本上是 MAX 或 MIN 日期,所有三个部分都是日期、月份和年份。因此,如果用户输入了两个日期,即 17/05/2018 和 17/04/2018,那么如果使用 MAX,则应显示第一个日期。

【问题讨论】:

  • 你需要设置 DATEFORMAT dmy;在运行查询之前。这应该会说服 SQL Server 使用 uk 日期格式,从而让 CAST 或 CONVERT 起作用
  • ntexttextimage 数据类型将在 SQL Server 的未来版本中删除。避免在新的开发工作中使用这些数据类型,并计划修改当前使用它们的应用程序。请改用nvarchar(max)varchar(max)varbinary(max)See details here。并存储 DATE - 你应该 REALLY 使用 DATEDATETIME2(n) - 不是任何基于字符串的数据类型!!

标签: sql sql-server reporting-services type-conversion


【解决方案1】:

您可以在使用 CONVERT 时使用格式代码,甚至可以使用 TRY_CONVERT 来防止无效日期导致的错误。我还改进了您的代码,使其更简单、更高效。

SELECT  [user_id], 
        record_id,
        MAX(CASE WHEN SUH.field_id = 4782 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS onSale,
        MAX(CASE WHEN SUH.field_id = 4783 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS OffSale
FROM  UPLOADS.RECORDS AS UR 
JOIN  UPLOADS.LINES AS SUH ON SUH.record_id = UR.record_id
WHERE  module_id = 18
GROUP BY [user_id], 
        record_id;

【讨论】:

    【解决方案2】:

    在 SQL 方面,这比 Luis 的回答略有改进:

    SELECT ur.[user_id], ur.record_id,
           MAX(CASE WHEN SUH.field_id = 4782 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS onSale,
           MAX(CASE WHEN SUH.field_id = 4783 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS OffSale
    FROM  UPLOADS.RECORDS UR LEFT JOIN
          UPLOADS.LINES AS SUH
          ON SUH.record_id = UR.record_id AND
             SUH.field_id IN (4782, 4783)
    WHERE ur.module_id = 18
    GROUP BY ur.[user_id], ur.record_id;
    

    也就是说,您的问题是您的数据不是您认为的格式。因此,类型转换的问题。正如@marc_s 在评论中所说,您应该使用 SQL 原生和适当的类型,在本例中为 DATE。而且您当然不应该使用已弃用的类型,例如 TEXT(除非您真的只是指 VARCHAR() 并且没有意识到存在已弃用的 TEXT 类型)。如果您在字符串中存储值(因为有不同的类型),您应该使用标准格式,YYYYMMDD 或 YYYY-MM-DD。

    你可以通过运行找到这些值:

    select suh.value
    from uploads.lines suh
    where suh.field_id in (4782, 4783) and
          try_convert(date, suh.value, 103) is null and
          suh.value is not null;
    

    这可以帮助您修复数据。

    固定数据后,还可以固定类型:

    update uploads.lines
        set suh.value = convert(varchar(255), convert(date, suh.value, 103), 112);  -- this will convert the value to the default date format
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多