我有一個要求,我必須從字串中提取日期/時間值,但問題是它們可以是不同的格式,因為子字串變得更加復雜。
這是我想出的,但有沒有其他方法可以簡單地檢索不同格式的日期和時間并將它們全部轉換為單一格式?
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp (
comments varchar(500)
)
insert into #temp (comments)
(
select 'Mailed on 1/1/22 at 5 pm'
union
select 'Mailed on 01/2/2222 @ 6 am'
union
select 'Mailed on 01/2/22 in night'
union
select 'Mailed on 1/02/2222 at 4 pm'
union
select 'Mailed on 1/1/2222 at 4 pm'
);
select *
from #temp
cross apply (select PATINDEX('%Mailed On%',comments) as start_pos) as start_pos
cross apply (select case when substring(comments,patindex('%Mailed On%',comments) 9,11) like '%[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%' then 1
when substring(comments,patindex('%Mailed On%',comments) 9,8) like '%[0-9][0-9]/[0-9]/[0-9][0-9]%' then 2
when substring(comments,patindex('%Mailed On%',comments) 9,10) like '%[0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]%' then 3
when substring(comments,patindex('%Mailed On%',comments) 9,9) like '%[0-9][0-9]/[0-9][0-9]/[0-9][0-9]%' then 4
when substring(comments,patindex('%Mailed On%',comments) 9,9) like '%[0-9]/[0-9]/[0-9][0-9][0-9][0-9]%' then 5
when substring(comments,patindex('%Mailed On%',comments) 9,7) like '%[0-9]/[0-9]/[0-9][0-9]%' then 6 else null end as substr) as substr
--cross apply (select case when substring(authcomments,start_pos 9, 11) like '%[1-9]/[0123][0-9]/[0-9][0-9][0-9][0-9]%' then 1 else null end as substr) as substr
cross apply (select case when substr = 1 then substring(comments,patindex('%Mailed On%',comments) 9,11)
when substr = 2 then substring(comments,patindex('%Mailed On%',comments) 9,8)
when substr = 3 then substring(comments,patindex('%Mailed On%',comments) 9,10)
when substr = 4 then substring(comments,patindex('%Mailed On%',comments) 9,9)
when substr = 5 then substring(comments,patindex('%Mailed On%',comments) 9,9)
when substr = 6 then substring(comments,patindex('%Mailed On%',comments) 9,7)
else null end as maileddate
) as maileddate
uj5u.com熱心網友回復:
@用戶1672315,
有時你會得到這樣的東西,為了修復它,以便你可以將日期和時間存盤在表格或其他任何東西中,你必須做你必須做的事情才能得到它,與評論相反,它當然可以在 SQ L 中完成。這并不難。你只需要知道一些“ gazintas ”;)
因此,使用您提供的易于使用的測驗資料,針對它運行以下代碼...
SELECT t.*
,TheDateAndTime = DATEADD(hh,ca4.cHour,ca3.cDate)
FROM #temp t
CROSS APPLY(VALUES(SUBSTRING(comments,PATINDEX('%[0-9]%',comments),500))) ca1(DT)
CROSS APPLY(VALUES(SUBSTRING(ca1.dt,PATINDEX('% [0-9]%',ca1.dt),500))) ca2(TM)
CROSS APPLY(VALUES(TRY_CONVERT(DATETIME,SUBSTRING(ca1.DT,1,PATINDEX('%[0-9] %',ca1.DT))))) ca3(cDate)
CROSS APPLY(VALUES(IIF(ca2.TM LIKE '%night%',23,DATEPART(hh,TRY_CONVERT(DATETIME,ca2.TM)))))ca4(cHour)
;
...并看到您可以在 SQL 中執行此操作...但是,請參閱下圖下方的警告。
您還需要弄清楚將分配什么時間“夜晚”。我將“23”指定為小時。
結果如下:

不過,我認為您的“2222”年是錯誤的。:D
我同意的一件事是格式需要保持一致。當 dd 和 mm 都小于 13 時,世界上沒有任何代碼(Python 或其他代碼)能夠區分 mm-dd-yy 和 dd-mm-yy 格式。我發布的代碼假定 (m)m-( d)d-yy 并且基于我正在使用的當前語言和日期格式。如果 mm 部分不在 1 到 12 之間,或者 dd 部分不在 1 到 31 之間,或者日期是“非法日期”,例如 2/29/2021 等,它將回傳 NULL。
它還假設該格式將始終包含數字日期作為它遇到的第一組數值,并且時間將始終是字串中的最后一件事。如果需要,我們可以添加更多檢查,但就像我說的,除非 mm >=13,否則它不能(也不能)確定它應該是 mm-dd-yy 還是 dd-mm-yy,因為根本沒有其他字串中的資訊以指示正在使用的格式。您也必須檢查您的日期格式才能使用它。如果字串應該是 dd-mm-yy 格式,我們可能必須進行更改(盡管我相信如果 DATEFORMAT 與字串的意圖匹配,SQL 服務器會自動適應這種情況)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/435012.html
