snippetsqlMinor
How to handle divide by zero in GENERATED columns in MySQL
Viewed 0 times
dividegeneratedcolumnshandlemysqlhowzero
Problem
I am using
but sometimes the
but can be a little problematic - for example for
GENERATED AS columns in MySQL 5.7 as follows:ALTER TABLE report_user
MODIFY avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/(trans_out_count))) STORED;but sometimes the
trans_out_count could be 0, then the GENERATED AS column will give a divide by zero error. So, what I did was:ALTER TABLE report_user
MODIFY avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/(trans_out_count + 0.00001))) STORED;but can be a little problematic - for example for
100,000/1.00001, the right value is 100,000, but the actual value it not correct 9,999.90. What should I do to handle this problem? This is the table DML:CREATE TABLE `report_user` (
`trans_into_count` int(11) NOT NULL DEFAULT '0' COMMENT '转入次数',
`trans_out_count` int(11) NOT NULL DEFAULT '0' COMMENT '转出次数',
`trans_into_amount` bigint(11) NOT NULL DEFAULT '0' COMMENT '转入金额',
`trans_out_amount` bigint(11) NOT NULL DEFAULT '0' COMMENT '转出金额',
`avg_trans_into_amount` bigint(20) GENERATED ALWAYS AS (round((`trans_into_amount` / (`trans_into_count` + 0.00001)),0)) STORED,
`avg_trans_out_amount` bigint(20) GENERATED ALWAYS AS (round((`trans_out_amount` / (`trans_out_count` + 0.00001)),0)) STORED,
`user_name` varchar(256) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '用户名',
`user_id` bigint(20) NOT NULL COMMENT '用户ID'
) ENGINE=InnoDB AUTO_INCREMENT=36149 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='提转统计';Solution
There are three ways to handle
1) USING
2) USING
3) USING
DIVIDE BY ZERO error in your case :1) USING
IF() :ALTER TABLE report_user
modify avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/if(trans_out_count,0,1))) STORED;2) USING
NULLIF() :ALTER TABLE report_user
modify avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/nullif(trans_out_count,1))) STORED;3) USING
GREATEST() :ALTER TABLE report_user
MODIFY avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/greatest(trans_out_count,1))) STORED;Code Snippets
ALTER TABLE report_user
modify avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/if(trans_out_count,0,1))) STORED;ALTER TABLE report_user
modify avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/nullif(trans_out_count,1))) STORED;ALTER TABLE report_user
MODIFY avg_trans_out_amount bigint
GENERATED ALWAYS AS (round(trans_out_amount/greatest(trans_out_count,1))) STORED;Context
StackExchange Database Administrators Q#283296, answer score: 4
Revisions (0)
No revisions yet.