我的故事從一個問題開始,當時我發現了新的錯誤:
[22001][1690] 數據截斷:BIGINT UNSIGNED 值超出 '(`cur`.`count_rows` - `perv`.`count_rows`)' 的范圍
嗯,我明白發生了什么,我的差異小于零,但是需要做什么呢?
我有大約下表:
CREATE TABLE daily_count_rows (
created_day DATE NOT NULL PRIMARY KEY,
count_rows BIGINT UNSIGNED NOT NULL
);
以及下面拋出“值超出范圍”錯誤的查詢
SELECT cur.created_day - prev.created_day
FROM daily_count_rows cur
INNER JOIN daily_count_rows prev ON prev.id= cur.table_schema
AND perv.created_day = CURDATE() - INTERVAL 1 DAY
WHERE cur.created_day = CURDATE()
第一個動作,像任何其他程序員一樣,試圖在 StackOverflow 上找到這個問題,我找到了解決方案,在查詢前添加 sql_mode:
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
SELECT ts.count_rows - ts2.count_rows AS rows_diff
-- ...
但是如果您無權更改 SQL_MODE 怎么辦?
我們有什么問題?
第一個變量 ts.count_rows 是 BIGINT UNSIGNED 類型,如果您嘗試計算和或差,計算的變量將是相同類型。
因此,讓我們嘗試使用 CAST 將類型轉換為所需的類型
SELECT CAST(ts.count_rows - ts2.count_rows AS SIGNED) AS rows_diff
我想你猜到這會拋出同樣的錯誤,因為 MySQL 會進行計算,然后轉換為有符號類型。
最后,我通過以下方式解決了這個問題:
SELECT IF(cur.created_day > prev.created_day,
cur.created_day - prev.created_day,
CAST(cur.created_day - prev.created_day as SIGNED) * -1
)
FROM daily_count_rows cur
INNER JOIN daily_count_rows prev ON prev.id= cur.table_schema
AND perv.created_day = CURDATE() - INTERVAL 1 DAY
WHERE cur.created_day = CURDATE();
如果您知道解決此問題的另一種方法,請與我分享。
謝謝!