前言
今天同事在同步完訂單數(shù)據(jù)后,由于訂單總金額和數(shù)據(jù)源的總金額存在差異,選擇使用LIMIT和SUM()函數(shù)計算當前分頁的總金額來和對方比較特定訂單的總金額,卻發(fā)現(xiàn)計算出來的金額并不是分頁的訂單總金額,而是所有訂單的總金額。
數(shù)據(jù)庫版本為mysql 5.7,下面會用一個示例復盤遇到的問題。
問題復盤
本次復盤會用一個很簡單的訂單表作為示例。
數(shù)據(jù)準備
訂單表建表語句如下(這里偷懶了,使用了自增ID,實際開發(fā)中不建議使用自增ID作為訂單ID)
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '訂單ID',
`amount` decimal(10,2) NOT NULL COMMENT '訂單金額',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
插入金額為100的SQL如下(執(zhí)行10次即可)
INSERT INTO `order`(`amount`) VALUES (100);
所以總金額為10*100=1000。
問題SQL
使用limit對數(shù)據(jù)進行分頁查詢,同時使用sum()函數(shù)計算出當前分頁的總金額
SELECT
SUM(`amount`)
FROM
`order`
ORDER BY `id`
LIMIT 5;
前面也提到了運行的結果,期待的結果應該為5*100=500,然而實際運行的結果卻為1000.00(帶有小數(shù)點是因為數(shù)據(jù)類型)
問題排查
其實如果對SELECT語句執(zhí)行順序有一定了解的朋友可以很快確定為什么返回的結果為所有的訂單總金額?下面我會就問題SQL的執(zhí)行書序來分析問題:
- FROM:FROM子句是最先執(zhí)行的,確定了查詢的是order這張表
- SELECT:SELECT子句是第二個執(zhí)行的子句,同時SUM()函數(shù)也在此時執(zhí)行了。
- ORDER BY:ORDER BY子句是第三個執(zhí)行的子句,其處理的結果只有一個,就是訂單總金額
- LIMIT:LIMIT子句是最后執(zhí)行的,此時結果集中只有一個結果(訂單總金額)
補充內(nèi)容
這里補充一下SELECT語句執(zhí)行順序
- FROM left_table>
- ON join_condition>
- join_type> JOIN right_table>
- WHERE where_condition>
- GROUP BY group_by_list>
- HAVING having_condition>
- SELECT
- DISTINCT select_list>
- ORDER BY order_by_condition>
- LIMIT limit_number>
解決辦法
遇到需要統(tǒng)計分頁數(shù)據(jù)時(除了SUM()函數(shù)外,常見的COUNT()、AVG()、MAX()、MIN()函數(shù)也存在這個問題),可以選擇使用子查詢來處理(PS:這里不考慮內(nèi)存計算,針對的是使用數(shù)據(jù)庫解決這個問題)。上面的問題解決方案如下:
SELECT
SUM(o.amount)
FROM
(SELECT
`amount`
FROM
`order`
ORDER BY `id`
LIMIT 5) AS o;
運行的返回值為500.00。
總結
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- MySQL查詢優(yōu)化:LIMIT 1避免全表掃描提高查詢效率
- 為什么MySQL分頁用limit會越來越慢
- mysql優(yōu)化之query_cache_limit參數(shù)說明
- 詳解Mysql order by與limit混用陷阱
- mysql分頁的limit參數(shù)簡單示例
- MySQL limit分頁大偏移量慢的原因及優(yōu)化方案
- Mysql排序和分頁(order by&limit)及存在的坑
- MySQL limit使用方法以及超大分頁問題解決
- 如何提高MySQL Limit查詢性能的方法詳解
- MySQL Limit性能優(yōu)化及分頁數(shù)據(jù)性能優(yōu)化詳解
- 淺談mysql使用limit分頁優(yōu)化方案的實現(xiàn)
- MySQL中l(wèi)imit對查詢語句性能的影響