MySQL函數sum使用場景解讀

文章簡介

今天分享一下MySQL中的sum函數使用。該函數已經成爲大家操作MySQL數據庫中時常用到的一個函數,這個函數統計滿足條件行中指定列的和,想必肯定大家都知道了,本身就沒什麼講頭了,這篇文章主要是通過幾個小案例深入瞭解一下該函數,以及在做MySQL查詢時如何使用sum函數做優化。

語法分析

SUM([DISTINCT] expr) [over_clause]

  1. 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.

  2. If there are no matching rows, SUM() returns NULL.

  3. This function executes as a window function if over_clause is present.

上面幾句是MySQL官方文檔的一個功能描述。這裏翻譯一下大致的意思是什麼。

  1. 返回expr表達式的和。如果沒有返回行數,則返回NULL。這裏的DISTINCT是爲了去掉表達式expr中的重複值。

  2. 如果沒有匹配到行,該函數也返回NULL。

  3. 如果設置了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

相關閱讀

全面分析與總結 MySQL 事務中那些事兒

MySQL事務最全詳解

MySQL慢查詢日誌操作


本文分享自微信公衆號 - 卡二條的技術圈(qq1005349393)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章