簡體   English   中英

MySQL:使用查詢中的特殊正則表達式規則修復時間格式

[英]MySQL: Fix time format using special regex rules inside query

我有一個關於MySQL內部時間字段的怪異問題。

在數據庫中,我們有2個字段: datetime 數據如下所示:

+-----------------------+
|   date   |    time    |
+-----------------------+
|27/04/2017|    11:30   |
+-----------------------+
|01/05/2017|    20u     |
+-----------------------+
|02/05/2017|    20u30   |
+-----------------------+
|03/05/2017|    21h     |
+-----------------------+

這些數據是什么意思? 好:

  • 20u是20:00
  • 20u30是20:30
  • 21h是21:00

主要問題是由於某些原因,我必須保持所有這些數據不變,並且必須找到解決方案以正確顯示數據,並從此抓取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查詢中的時間?

謝謝!

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來解決這種表示形式的廢話。

現在,關於您要求的解決方法的步驟:

  • 首先,如果您忽略分鍾,則它們隱式為“ 00”,因此“ 20u”為“ 20u00”。 現在,如果僅添加兩個零,然后在第五個字符后截斷,則最終將得到標准化的元組。 例如“ 20u”->“ 20u00”->“ 20u00”或“ 20:00”->“ 20:0000”->“ 20:00”。
  • 其次,小時和分鍾之間的分隔符似乎是冒號或拉丁文小寫字母u,因此“ 20:15”是“ 20u15”。 這意味着,如果您僅刪除此字母(將第一個,第二個,第四個和第五個字母組合在一起),則會得到規范的表示。 例如“ 20:30”->“ 2030”或“ 20u30”->“ 2030”。

另外一個好處是,它甚至不嘗試使用正則表達式,因為正則表達式既昂貴又容易出錯。 但是,它依賴於列內容正是您編寫的內容而沒有例外。

暫無
暫無

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

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