簡體   English   中英

在SQL中將字符串轉換為日期時間

[英]Convert string to datetime in sql

我有一個數據庫表,其中3列分別是ID,鍵和值。 ID字段是一個整數,鍵是varchar(50),值是varchar(100)。

我對該表的樣本數據如下:

ID          Key                 Value
1           Template            one
2           RequestedOn         15/04/2014 12:12:27
3           PrintedOn           15/04/2014 12:12:37
4           Template            two
5           RequestedOn         16/04/2014 12:22:27
6           PrintedOn           16/04/2014 12:22:37
7           Template            three
8           RequestedOn         17/05/2014 12:32:27
9           PrintedOn           17/05/2014 12:32:37
:
:
45          RequestedOn         17/06/2014 12:22:27
46          PrintedOn           17/06/2014 12:22:37
47          Template            three
48          RequestedOn         17/06/2014 12:32:27
49          PrintedOn           17/06/2014 12:32:37

我希望能夠查詢表以返回某些日期范圍之間的值。

例如:

我想返回PrintedOn在17/06/2014 12:22:27和17/06/2014 12:32:37之間的所有行

我嘗試了以下查詢,但得到“將字符串轉換為smalldatetime數據類型時轉換失敗。” 信息。

SET DATEFORMAT DMY
;with cte as
(
select CONVERT(datetime, CAST(Value as smalldatetime)) as PrintedOn
from ExtendedProperties 
where isdate(Value) = 1 
)
select * from cte where PrintedOn > '17/05/2014' and PrintedOn < '17/06/2014'

免責聲明: OP在回答中未指定他使用的SQLServer版本,假定該版本為SQLServer 2012或更高版本。

第一步應該是使用PIVOT或偽造的PIVOT獲取數據。

使用假設密鑰“模板”將始終在其他兩個模板之前的假設,可以使用此方法

SELECT [Template]
     , Try_Parse(RequestedOn as DATETIME2 USING 'it-IT') RequestedOn
     , Try_Parse(PrintedOn as DATETIME2 USING 'it-IT') PrintedOn
FROM   (SELECT [Key], Value
             , ID = SUM(CASE WHEN [Key] = 'Template' THEN 1 ELSE 0 END)
                   OVER(ORDER BY ID)
        FROM   Table1) d
       PIVOT
       (MAX(Value) FOR [Key] IN ([Template], [RequestedOn], [PrintedOn])) u

Try_Parse使用的是意大利文化,因為它是日期格式為dd / MM / yyyy的國家之一,使用具有不同格式的文化會導致NULL值。

擁有所有這些只是查詢VIEW / CTE ,這里我將使用CTE

With T AS (
  SELECT [Template]
       , Try_Parse(RequestedOn as DATETIME2 USING 'it-IT') RequestedOn
       , Try_Parse(PrintedOn as DATETIME2 USING 'it-IT') PrintedOn
  FROM   (SELECT [Key], Value
               , ID = SUM(CASE WHEN [Key] = 'Template' THEN 1 ELSE 0 END)
                     OVER(ORDER BY ID)
          FROM   Table1) d
         PIVOT
         (MAX(Value) FOR [Key] IN ([Template], [RequestedOn], [PrintedOn])) u
)
SELECT *
FROM   T
WHERE  PrintedOn BETWEEN '20140617 12:22:27' and '20140617 12:32:37'

SQLFiddle演示

結果將采用以下格式

Template | RequestedOn | PrintedOn
---------+-------------+----------
value    | date        | date

如果使用SQL Server 2012,則可以用TRY CAST替換CAST。 這是語法示例

Declare @string as varchar(7)
Set @string ='raresql'    
SELECT Try_Cast(@string as smalldatetime) as [Cast Text to smalldatetime]

在這種情況下,“三”之類的值將返回null而不是異常。

使用CASE,您只能在Value包含日期的情況下進行轉換

;with cte as
(
select  Case when isdate(Value) = 1  then CAST(Value as datetime) else NULL end  as PrintedOn
from @t 
where Case when isdate(Value) = 1  then CAST(Value as datetime) else NULL end is not NULL
)
select * from cte where PrintedOn > '17/05/2014' and PrintedOn < '17/06/2014'

這里是一個小提琴的解決方案......。

create table test (value varchar(100))

insert into test
select 'one' union
select '15/04/2014 12:12:27' union
select 'two' union
select '16/04/2014 12:22:27'

set dateformat dmy
;with cte as
(
select case when isdate(value)=1 then convert(datetime, value) else null end as PrintedOn
from test 
where isdate(Value) = 1 
)
select * from cte

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM