簡體   English   中英

如何在 MySQL 查詢中避免浮點運算?

[英]How to avoid floating-point arithmetic in a MySQL query?

假設我有兩列 A 和 B,它們的類型為DECIMAL(9,2)

現在,假設我運行以下查詢:

SELECT SUM(A) / SUM(B)

我的理解是,這種除法不會通過浮點運算完成,因為兩列都是DECIMAL類型。 這個對嗎?

另外,假設我運行以下查詢:

SELECT SUM(A) / SUM(B) * 100

100將如何影響查詢? 這會以某種方式導致 MySQL 進行浮點運算嗎? 如果是這樣,我該如何避免它?

這會以某種方式導致 MySQL 進行浮點運算嗎?

我想說你應該參考 SQL 標准,但作為 MySQL,可能不是解決實踐中會發生什么的最可靠方法:)。

我怎樣才能避免[意外的浮動演員]?

我要做的是明確地將值歸為適合您的類型:

SUM(A) / SUM(B) * CAST(100.0 AS DECIMAL(9,2)) 

明確並有助於為未來的您提供文檔。

100 將如何影響查詢? 這會以某種方式導致 MySQL 進行浮點運算嗎? 如果是這樣,我該如何避免它?

100 是一個精確值的數字文字,這里我們用小數除以小數乘以小數(整數)=> 結果仍然是小數(但精度更高)。

數字文字

精確值數字文字具有 integer 部分或小數部分,或兩者兼而有之。 他們可能會簽名。 示例:1、.2、3.4、-5、-6.78、+9.10。

近似值數字文字以科學記數法表示,帶有尾數和指數。 可以簽署其中一個或兩個部分。 示例:1.2E3、1.2E-3、-1.2E3、-1.2E-3。

兩個看起來相似的數字可能會被區別對待。 例如,2.34 是一個精確值(定點)數,而 2.34E0 是一個近似值(浮點)數。

例子:

CREATE TABLE t(A DECIMAL(9,2), B DECIMAL(9,2));

CREATE TABLE r1 AS SELECT SUM(A) / SUM(B) AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r1';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | decimal(37,6) |
+--------------+---------------+

CREATE TABLE r2 AS SELECT SUM(A) / SUM(B) * 100 AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r2';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | decimal(40,6) |
+--------------+---------------+

現在使用近似值數字文字100E0

CREATE TABLE r3 AS SELECT SUM(A) / SUM(B) * 100E0 AS result FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r3';
+--------------+-------------+
| COLUMN_NAME  | COLUMN_TYPE |
+--------------+-------------+
| result       | double      |
+--------------+-------------+

db<>小提琴演示


值得注意的是,某些操作可能看起來完全相同,但返回的數據類型不同。 例如:

CREATE TABLE r4 AS SELECT POWER(A,2) AS result, A*A AS result2 FROM t;

SELECT column_name, column_type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'r4';
+--------------+---------------+
| COLUMN_NAME  |  COLUMN_TYPE  |
+--------------+---------------+
| result       | double        |
| result2      | decimal(18,4) |
+--------------+---------------+

與其爭論計算的細節,不如格式化結果。 例如:

SELECT ROUND(100 * sum(...) / sum(...), 1) ...

這給你百分比到小數點后一位。

當您需要“千位分隔符”(不太可能用於百分比)時,請參閱FORMAT() function。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM