[英]MySQL: Fix time format using special regex rules inside query
我有一個關於MySQL內部時間字段的怪異問題。
在數據庫中,我們有2個字段: date
和time
。 數據如下所示:
+-----------------------+
| date | time |
+-----------------------+
|27/04/2017| 11:30 |
+-----------------------+
|01/05/2017| 20u |
+-----------------------+
|02/05/2017| 20u30 |
+-----------------------+
|03/05/2017| 21h |
+-----------------------+
這些數據是什么意思? 好:
主要問題是由於某些原因,我必須保持所有這些數據不變,並且必須找到解決方案以正確顯示數據,並從此抓取unix時間戳或正確的日期或匹配正確的日期。
為了讓您理解我的需求,Query的舊部分看起來像這樣:
UNIX_TIMESTAMP(CONCAT(DATE_FORMAT(STR_TO_DATE(`date`,'%d/%m/%Y'),'%Y-%m-%d'),' ',`time`))
但這無法匹配正常情況。
我編寫了一個PHP函數來在代碼的某些部分上顯示適當的時間,如下所示:
function bo_time($string)
{
if(preg_match("/(\d{1,2})(u|h)/Ui",$string, $match))
{
$string = sprintf("%s:%s", sprintf('%02d', $match[1]), '00' );
}
else if(preg_match("/(\d{1,2})(u|h|\:)(\d{2})/Ui",$string, $match))
{
$string = sprintf("%s:%s", sprintf('%02d', $match[1]), ( isset($match[3]) ? sprintf('%02d', $match[3]) : '00' ));
}
return $string;
}
使用該PHP函數,系統的某些部分可以正常工作,但是在系統的某些部分中,我可以按日期/時間在表之間進行匹配,並且一切都會失敗並破裂。
我的主要問題是:
有沒有辦法像在PHP中那樣編寫一些正則表達式來轉換MySQL查詢中的時間?
謝謝!
如果必須保持所有現有數據不變,是否可以創建一個具有正確日期時間格式的新字段並開始使用它呢?
您可以繼續使用PHP函數來轉換數據,並在某些情況下看到失敗,您可能想要首先解決這些問題。
我能夠用更少的代碼來完成您的PHP函數的工作:
// $time = 20u30
preg_replace(['/[uh]/i','/:(?![0-9]+)/'], [':',':00'], $time);
我創建了一個查詢,該查詢至少對您提供給我們的數據有效。 只需一些邏輯即可處理數據的各種邊緣情況。 我將您的時間數據轉換為實際的時間戳記時間字符串,然后與日期連接,也轉換為ISO格式。 有了適當的日期和時間后,我們可以在此時間戳字符串上調用UNIX_TIMESTAMP
以獲取所需的數據。
SELECT
date, time, UNIX_TIMESTAMP(CONCAT(date, ' ', time)) AS ts
FROM
(
SELECT
CONCAT(RIGHT(date, 4), '-', SUBSTRING(date, 4, 2), '-',
LEFT(date, 2)) AS date,
CASE WHEN time REGEXP '.*[uh]$'
THEN CONCAT(LEFT(time, CHAR_LENGTH(time) - 1), ':00:00')
ELSE CONCAT(REPLACE(REPLACE(time, 'h', ':'),
'u', ':'), ':00') END AS time
FROM yourTable
) t;
輸出:
演示在這里:
首先,將這種表示形式保留在數據庫中似乎完全不合理。 似乎time
列有一個規范的表示形式(例如20:11),您可以調整每個字段以僅具有該表示形式。 如果這樣做的話,您將不必創建hack來解決這種表示形式的廢話。
現在,關於您要求的解決方法的步驟:
另外一個好處是,它甚至不嘗試使用正則表達式,因為正則表達式既昂貴又容易出錯。 但是,它依賴於列內容正是您編寫的內容而沒有例外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.