文章簡介
今天分享一下MySQL中的sum函數使用。該函數已經成爲大家操作MySQL數據庫中時常用到的一個函數,這個函數統計滿足條件行中指定列的和,想必肯定大家都知道了,本身就沒什麼講頭了,這篇文章主要是通過幾個小案例深入瞭解一下該函數,以及在做MySQL查詢時如何使用sum函數做優化。
語法分析
SUM([DISTINCT] expr) [over_clause]
-
Returns the sum of expr. If the return set has no rows, SUM() returns NULL. The DISTINCT keyword can be used to sum only the distinct values of expr.
-
If there are no matching rows, SUM() returns NULL.
-
This function executes as a window function if over_clause is present.
上面幾句是MySQL官方文檔的一個功能描述。這裏翻譯一下大致的意思是什麼。
-
返回expr表達式的和。如果沒有返回行數,則返回NULL。這裏的DISTINCT是爲了去掉表達式expr中的重複值。
-
如果沒有匹配到行,該函數也返回NULL。
-
如果設置了over_clause,則該函數作爲窗口函數執行。對窗口函數不熟悉的,可以去了解一下MySQL中的窗口函數。
函數解釋
在使用該函數時,我們應該思考一下,該函數是如何統計表達式中的和呢?可能有的程序員會想,這個函數直接去統計滿足條件中所有行的總和。這麼理解其實也沒錯,只是表達的不是很準確或者他不夠真實瞭解運行原理。
實際上該函數是根據匹配行的值,一個一個累加起來的。這裏舉個例子,在一個訂單表中滿足條件的有10行數據,我們需要統計訂單中的總價,sum的初始值是0,在匹配到第一行時,訂單價格是10,此時sum就變成10,匹配到第二行,訂單價格是20,這時候sum就是30。第三行訂單價格是50,這時候sum就是80。按照這種方式依次累加。
行數 | 訂單價格 | sum值 |
---|---|---|
第一行 | 10.00 | 10.00 |
第二行 | 20.00 | 30.00 |
第三行 | 30.00 | 60.00 |
第四行 | 40.00 | 100.00 |
第五行 | 50.00 | 150.00 |
第...行 | ... | ... |
第十行 | 100.00 | 550.00 |
實例演示
假設有下面一張表(Delivery),表結構如下:
+-----------------------------+---------+
| Column Name | Type |
+-----------------------------+---------+
| delivery_id | int |
| customer_id | int |
| order_date | date |
| customer_pref_delivery_date | date |
| order_money | decimal |
+-----------------------------+---------+
delivery_id 是表的主鍵。該表保存着顧客的食物配送信息,顧客在某個日期下了訂單,並指定了一個期望的配送日期(和下單日期相同或者在那之後)。如果顧客期望的配送日期和下單日期相同,則該訂單稱爲 「即時訂單」,否則稱爲「計劃訂單」。裏面有如下數據:
+-------------+-------------+------------+-----------------------------+-------------+
| delivery_id | customer_id | order_date | customer_pref_delivery_date | order_money |
+-------------+-------------+------------+-----------------------------+-------------+
| 1 | 1 | 2019-08-01 | 2019-08-02 | 1.23 |
| 2 | 5 | 2019-08-02 | 2019-08-02 | 1.01 |
| 3 | 1 | 2019-08-11 | 2019-08-11 | 1.09 |
| 4 | 3 | 2019-08-24 | 2019-08-26 | 1.00 |
| 5 | 4 | 2019-08-21 | 2019-08-22 | 10.00 |
| 6 | 2 | 2019-08-11 | 2019-08-13 | 12.09 |
+-------------+-------------+------------+-----------------------------+-------------+
實例一
統計出該表中所有的訂單總金額。這裏就很簡單了,也是我們常用的使用方式,直接sum()參數填寫某一個列就行了。按照上面的語法規則應該是一個表達式,實際上一列也是一個表達式。
select sum(order_money) from Delivery;
實例二
寫一條 SQL 查詢語句獲取即時訂單所佔的百分比, 保留兩位小數。這個可能就有一點點難度了,因爲你很少用這個語法,如果你用過,就會發現也很簡單。首先你要理解,既然是查詢某一個類型的佔比,肯定就需要統計總和。我們可以分別去統計到訂單總和 sum2。然後在相除就可以了。但是這裏明確要求一條SQL語句。那該如何解決呢?這裏就需要你深入瞭解一下sum的運行原理,我們可以設想我們一行一行的去讀取數據,然後讓sum一行一行的累計起來,是不是就可以得到 sum1肯定很好統計,直接是表中行數的綜合。
題解方式一:
select round (
sum(case when order_date = customer_pref_delivery_date then 1 else 0 end) /
count(*) * 100,
2
) as immediate_percentage
from Delivery
題解方式二:
select round (
sum(order_date = customer_pref_delivery_date) /
count(*) * 100,
2
) as immediate_percentage
from Delivery
這裏當sum表達式滿足條件,返回1,每次讀到滿足的一行數據,sum都加1,最後數據讀完sum也就加完了。因此滿足條件的總條數就出來了。
題目來源
改題目來源於LeetCode。
來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/immediate-food-delivery-i 著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
還有一個比較不錯的例子,推薦好好解讀一下。加深該函數的使用場景。
https://www.jianshu.com/p/c19c99a60bb7
相關閱讀
本文分享自微信公衆號 - 卡二條的技術圈(qq1005349393)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。