SELECT alertid,
ackuid,
severity,
ticketid,
From_unixtime(display_ts) AS Detection_Time,
From_unixtime(ack_ts) AS Ack_Time,
Round(( ack_ts - display_ts ) / 60) AS MTTA_MINS,
IF (Round(( ack_ts - display_ts ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM alerts_test
WHERE display_ts > Unix_timestamp(Now() - INTERVAL 26 day)
ORDER BY From_unixtime(display_ts);
错误1690(22003):BIGINT UNSIGNED值超出范围 '(
dba
。DBA_IRIS_ALERTS
。ack_ts
-dba
。DBA_IRIS_ALERTS
。display_ts
)'
如何解决此错误?尤其是在这种情况下,它会失败。
round((ack_ts-display_ts)/60) as MTTA_MINS,
IF ( round((ack_ts-display_ts)/60) > 15, 1, 0) as SLA_MISSED
样本数据
+----------------------------------+-----------------+----------+-------------+---------------------+---------------------+-----------+------------+
| alertid | ackuid | severity | ticketid | Detection_Time | Ack_Time | MTTA_MINS | SLA_MISSED |
+----------------------------------+-----------------+----------+-------------+---------------------+---------------------+-----------+------------+
| xxxxxx | him | 5 | NULL | 2018-11-01 00:03:23 | 2018-11-01 00:06:18 | 3 | 0 |
| xxxxxx | him | 5 | NULL | 2018-11-01 00:11:08 | 2018-11-01 00:17:45 | 7 | 0 |
答案 0 :(得分:1)
来自Out-of-Range and Overflow Handling:
整数值之间的减法,其中一个是UNSIGNED类型的, 默认情况下会产生未签名的结果。如果结果不然 一直为负,则导致错误:
mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> SELECT CAST(0 AS UNSIGNED) - 1; ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
因此,我认为ack_ts
和/或display_ts
列(似乎代表Unix时间戳值)是在UNSIGNED
中使用CREATE TABLE
标志定义的语句(很好,因为Unix Timestamp值应仅为正值)。
因此,您要减去UNSIGNED
类型的列,而ack_ts - display_ts
的结果为负。因此,您遇到ack_ts
<display_ts
的情况。
现在,有两种可能性:
ack_ts
<display_ts
的情况。 在这种情况下,您将需要向查询添加另一个WHERE
条件:
SELECT alertid,
ackuid,
severity,
ticketid,
From_unixtime(display_ts) AS Detection_Time,
From_unixtime(ack_ts) AS Ack_Time,
Round(( ack_ts - display_ts ) / 60) AS MTTA_MINS,
IF (Round(( ack_ts - display_ts ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM alerts_test
WHERE display_ts > Unix_timestamp(Now() - INTERVAL 26 day) AND
ack_ts >= display_ts /* added one more condition to remove negative cases */
ORDER BY From_unixtime(display_ts);
在这种情况下,您需要将它们强制转换为SIGNED
,以使计算结果为负值:
SELECT alertid,
ackuid,
severity,
ticketid,
From_unixtime(display_ts) AS Detection_Time,
From_unixtime(ack_ts) AS Ack_Time,
Round(( CAST(ack_ts AS SIGNED) - CAST(display_ts AS SIGNED) ) / 60) AS MTTA_MINS,
IF (Round(( CAST(ack_ts AS SIGNED) - CAST(display_ts AS SIGNED) ) / 60) > 15, 1, 0) AS SLA_MISSED
FROM alerts_test
WHERE display_ts > Unix_timestamp(Now() - INTERVAL 26 day)
ORDER BY From_unixtime(display_ts);
另一种选择是将sql_mode
设置为使用NO_UNSIGNED_SUBTRACTION
。现在,您可以在设置模式后使用原始查询:
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
您可能无权全局更改此设置。因此,您可以在原始查询之前运行以下查询,以仅针对特定的客户端会话进行此更改。
SET SESSION sql_mode = 'NO_UNSIGNED_SUBTRACTION';
检查此答案以获取有关设置sql_modes的更多详细信息:https://stackoverflow.com/a/26104070/2469308