|
|
|
|
|
我們在MySQL計算兩日期時間差時,往往是使用算術(shù)表達式來計算直接獲得結(jié)果,但當(dāng)兩字段數(shù)據(jù)類型不同時,獲得的結(jié)果是一串難以理解的數(shù)字。為此,我們需要更新這種寫法,要以獲得易理解易閱讀和易用結(jié)果為目標,這是本文的初衷,而一個很簡單的CAST()
函數(shù),就能滿足我們的要求。
介紹
CAST()
函數(shù)用于將某種數(shù)據(jù)類型的表達式顯式轉(zhuǎn)換為另一種數(shù)據(jù)類型。CAST()
函數(shù)的參數(shù)是一個表達式,它包括用AS
關(guān)鍵字分隔的源值和目標數(shù)據(jù)類型。
語法:
CAST (expression AS data_type)
示例
運行以下查詢,以start_time
減去end_time
計算小時數(shù)(提示:end_time
數(shù)據(jù)類型是TIMESTAMP
,start_time
數(shù)據(jù)類型是TIME
)。
SELECT runner_name, race_name, end_time - start_time
AS total_time
FROM race_results;
輸出:
Output
+-------------+---------------+----------------+
| runner_name | race_name | total_time |
+-------------+---------------+----------------+
| bolt | 1600_meters | 20220918000630 |
| bolt | 5K | 20221019002231 |
| bolt | 10K | 20221120003805 |
| bolt | half_marathon | 20221221013904 |
| bolt | full_marathon | 20230122032310 |
| felix | 1600_meters | 20220918000715 |
| felix | 5K | 20221019003050 |
| felix | 10K | 20221120011017 |
| felix | half_marathon | 20221221021157 |
| felix | full_marathon | 20230122040210 |
+-------------+---------------+----------------+
10 rows in set (0.00 sec)
可以看到,輸出包含一列很長的輸出,該輸出跟隨表中設(shè)置的TIMESTAMP
數(shù)據(jù)類型。
因為你正在使用具有不同數(shù)據(jù)類型(end_time
保存TIMESTAMP
值而start_time
保存TIME
值)的兩列執(zhí)行操作,所以數(shù)據(jù)庫在打印操作結(jié)果時不知道要使用哪種數(shù)據(jù)類型。相反,它將兩個值都轉(zhuǎn)換為整數(shù),以便可以執(zhí)行操作,從而在total_time
列中生成長數(shù)字。
為了幫助使這些數(shù)據(jù)更易于閱讀和解釋,你可以使用CAST()
函數(shù)將這些長整數(shù)值轉(zhuǎn)換為TIME
數(shù)據(jù)類型。為此,請先以CAST
開頭,跟著用左括號,然后是要轉(zhuǎn)換的值,再加上AS
關(guān)鍵字和要將其轉(zhuǎn)換成的數(shù)據(jù)類型,最后加上右括號。
以下查詢與前面的示例相同,但使用CAST()
函數(shù)將total_time
列轉(zhuǎn)換為TIME
數(shù)據(jù)類型:
SELECT runner_name, race_name, CAST(end_time - start_time AS time)
AS total_time
FROM race_results;
輸出:
Output
+-------------+---------------+------------+
| runner_name | race_name | total_time |
+-------------+---------------+------------+
| bolt | 1600_meters | 00:06:30 |
| bolt | 5K | 00:22:31 |
| bolt | 10K | 00:38:05 |
| bolt | half_marathon | 01:39:04 |
| bolt | full_marathon | 03:23:10 |
| felix | 1600_meters | 00:07:15 |
| felix | 5K | 00:30:50 |
| felix | 10K | 01:10:17 |
| felix | half_marathon | 02:11:57 |
| felix | full_marathon | 04:02:10 |
+-------------+---------------+------------+
10 rows in set (0.00 sec)
CAST
將輸出中的數(shù)據(jù)值轉(zhuǎn)換為TIME
,使其更易于閱讀和理解,以及使用。
使用聚合函數(shù)
現(xiàn)在,讓我們使用一些聚合函數(shù)結(jié)合CAST
來查找最短、最長和總時間結(jié)果。
首先,MIN
聚合函數(shù)查詢最少(或最短)時間。同樣,為了清楚起見,希望使用CAST
將TIMESTAMP
數(shù)據(jù)值轉(zhuǎn)換為TIME
數(shù)據(jù)值。請注意,當(dāng)使用本例中的兩個函數(shù)時,需要兩對括號,并且總小時數(shù) ( end_time
- start_time
) 的計算應(yīng)嵌套在其中一對括號內(nèi)。最后,添加一個GROUP BY
子句來根據(jù)runner_name列組織這些值,以便輸出顯示兩個跑步者的比賽結(jié)果:
SELECT runner_name, MIN(CAST(end_time - start_time AS time)) AS min_time
FROM race_results GROUP BY runner_name;
輸出:
Output
+-------------+----------+
| runner_name | min_time |
+-------------+----------+
| bolt | 00:06:30 |
| felix | 00:07:15 |
+-------------+----------+
2 rows in set (0.00 sec)
此輸出顯示每個跑步者的最短跑步時間,在本例中,Bolt 至少為 6 分 30 秒,F(xiàn)elix 為 7 分 15 秒。
接下來,找到每個跑步者的最長時間??梢允褂门c上一個查詢相同的語法,但這次替換MIN
為MAX
:
SELECT runner_name, MAX(CAST(end_time - start_time AS time)) AS max_time
FROM race_results GROUP BY runner_name;
輸出:
Output
+-------------+----------+
| runner_name | max_time |
+-------------+----------+
| bolt | 03:23:10 |
| felix | 04:02:10 |
+-------------+----------+
2 rows in set (0.00 sec)
這個輸出告訴我們,Bolt 最長的運行時間總共是 3 小時 23 分 10 秒;而 Felix 一共是 4 小時 2 分 10 秒。
現(xiàn)在讓我們查詢一些關(guān)于每個跑步者跑步總小時數(shù)的高級信息。對于此查詢,結(jié)合SUM
聚合函數(shù)以查找基于end_time - start_time
的總小時數(shù),并用CAST
將這些數(shù)據(jù)值轉(zhuǎn)換為TIME
。不要忘記包括GROUP BY
組織兩個跑步者結(jié)果的值:
SELECT runner_name, SUM(CAST(end_time - start_time AS time))
AS total_hours FROM race_results GROUP BY runner_name;
輸出:
Output
+-------------+-------------+
| runner_name | total_hours |
+-------------+-------------+
| bolt | 52880 |
| felix | 76149 |
+-------------+-------------+
2 rows in set (0.00 sec)
這個輸出顯示了 MySQL 的解釋,它實際上是以整數(shù)計算總時間。如果我們將這些結(jié)果解讀為時間,Bolt 的總時間為 5 小時 28 分 80 秒;Felix 的總時間為 7 小時 61 分 49 秒。這表明它是以整數(shù)而不是時間計算的。如果在不同的 DBMS(例如 PostgreSQL)中嘗試此操作,則相同的查詢看起來會略有不同:
SELECT runner_name, SUM(CAST(end_time - start_time AS time))
AS total_hours FROM race_results GROUP BY runner_name;
輸出:
Output
runner_name | total_hours
-------------+-------------
felix | 10:01:44
bolt | 06:09:20
(2 rows)
在這種情況下,PostgreSQL 中的查詢將值解釋為時間并按時間計算,因此 Felix 的結(jié)果分解為總共 10 小時、1 分鐘和 44 秒;而 Bolt 的時間是 6 小時 9 分 20 秒。這是一個示例,說明各種 DBMS 以不同方式解釋數(shù)據(jù)值,即使它使用相同的查詢和數(shù)據(jù)集。
總結(jié)
本教程僅對 SQL 中的日期和時間使用了加法和減法運算,但你可以將日期和時間值與任何數(shù)學(xué)表達式一起使用。從我們的數(shù)學(xué)表達式和聚合函數(shù)指南中了解更多信息,并在你的日期和時間查詢中試用它們。