<返回更多

MySQL中UNSIGNED整数类型的差异问题

2022-10-16  今日头条  庄志炎
加入收藏

 

我的故事从一个问题开始,当时我发现了新的错误:

[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();

如果您知道解决此问题的另一种方法,请与我分享。

谢谢!

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>