从时间间隔转换为语句

时间:2013-08-30 06:39:51

标签: sql sql-server

我正在尝试将数据库中的时间值更改为语句。例如,早晨06:00:00至12:00:00,下午12:00:00至17:00:00之间的时间间隔等等。我正在使用这种方法:

Update dbo.denouncement_term_day_time

Set time_den = 'Morning'

WHERE (DATEPART(HOUR, time_den) >= 6
  AND DATEPART(MINUTE, time_den) >= 00
  AND DATEPART(SECOND, time_den) >= 00) AND
  (DATEPART(HOUR, time_den) <= 11
  AND DATEPART(MINUTE, time_den) <= 59
  AND DATEPART(SECOND, time_den) <= 59)

但是现在,它无法正常工作,并且它给出了错误“从字符串转换日期和/或时间时转换失败”。即使时间是varchar。正如我所说,如果是前50-100行,它适用于相同的数据。但对于250,000 raw,它会出现此错误。

谢谢,

3 个答案:

答案 0 :(得分:1)

我几乎不知道从这个开始......

  1. 为什么要在varchar()字段上多次调用DATEPART?这需要首先隐式转换为日期时间类型,这将是昂贵的。将字符串转换为日期时间并从那里开始工作会好得多。

  2. 不要在数据库中存储“早晨”等。使用CASE根据日期时间值导出友好值。您可以直接在SELECT中执行此操作,也可以在VIEW中将其抽象出来。

  3. 在此字段上调用DATEPART()也意味着您将来肯定会收到错误,因为您在日期/时间字符串的位置设置了像'Morning'这样的字符串。

  4. DATEPART(MINUTE,x)&gt; = 0且DATEPART(SECOND,x)&gt; = 0将始终返回true。没有负面的分钟或秒钟。

  5. 同样,11:59:59的最后比较可以简化为DATEPART(HOUR,d)&lt; 12.轰隆隆。无需看几分钟或几秒钟。 (这也处理小数秒,你可能没有以字符串形式处理。

  6. 核心问题是varchar()字段中的某些内容不是可以隐式转换回来的日期/时间。

    我的解决方案,使用计算列:

      -- Add a new column for the proper datetime values.
      ALTER TABLE denouncement_term_day_time ADD datetime_den datetime;
      -- Clean your data before running the next line.
      UPDATE denouncement_term_day_time SET datetime_den = CAST(time_den AS datetime);
      -- Once converted, don't store the string dates anymore, it's wasteful
      ALTER TABLE denouncement_term_day_time DROP COLUMN time_den;
      -- Add a computed column to return the friendly time.
      ALTER TABLE denouncement_term_day_time ADD friendly_time AS
            CASE
              WHEN DATEPART(HOUR, datetime_den) > 16 THEN 'Evening'
              WHEN DATEPART(HOUR, datetime_den) > 11 THEN 'Afternoon'
              ELSE 'Morning'
            END
    

    然而,即使这样也存在问题,因为它假定用户与数据处于同一时区。理想情况下,这类事情应该在UI层中完成,您可以访问用户的位置,语言等,而不是深入数据层。

答案 1 :(得分:0)

试试这个 -

ALTER TABLE dbo.denouncement_term_day_time
    ADD time_den_new VARCHAR(20) NULL
GO

UPDATE dbo.denouncement_term_day_time
SET time_den_new = 
        CASE WHEN time_den BETWEEN '6:00:00' AND '11:59:59' THEN 'Morning'
             WHEN time_den BETWEEN '12:00:00' AND '16:59:59' THEN 'Afternoon'
        END
WHERE time_den BETWEEN '6:00:00' AND '16:59:59'
GO

ALTER TABLE dbo.denouncement_term_day_time DROP COLUMN time_den
GO

EXEC sp_rename 'dbo.denouncement_term_day_time.time_den_new', 'time_den', 'COLUMN'

答案 2 :(得分:0)

试试这个

Update dbo.denouncement_term_day_time
   Set time_den = 'Morning'
WHERE (DATEPART(HOUR,  Convert(DATETIME, [time_den]), 8)) >= 6
AND DATEPART(MINUTE,  Convert(DATETIME, [time_den]), 8)) >= 00
AND DATEPART(SECOND,  Convert(DATETIME, [time_den]), 8)) >= 00) 
AND ( DATEPART(HOUR,  Convert(DATETIME, [time_den]), 8)) <= 11
AND DATEPART(MINUTE,  Convert(DATETIME, [time_den]), 8)) <= 59
AND DATEPART(SECOND,  Convert(DATETIME, [time_den]), 8)) <= 59)