MariaDB 中 CAST() 和 COALESCE() 的顺序很重要
Order of CAST() and COALESCE() matters in MariaDB
我有一个奇怪的问题:在 table 的 JSON 列中有一个价格,以下语句给出不同的结果,但它们应该给出相同的结果:
CAST(COALESCE(JSON_EXTRACT(item.price_details, "$.shipping.price"), 0) AS FLOAT) AS shippricecoalfloat
COALESCE(CAST(JSON_EXTRACT(item.price_details, "$.shipping.price") AS FLOAT), 0) AS shippricefloatcoal
为了检查我还添加了一个 JSON_EXTRACT(item.price_details, "$.shipping.price") AS shipprice
结果:
MariaDB 版本:mariadb Ver 15.1 Distrib 10.3.31-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
DB Fiddle (I couldn't use the same MariaDB version but it behaves the same anyways apparently)
我相信这是您问题的“解决方案”:
select cast('"0.8648"' as float)
我将尝试解释我的看法...
首先要知道的是:“COALESCE() 具有与参数相同的数据类型。”
这个 COALESCE(JSON_EXTRACT(price_details, "$.shipping.price"), 0) as coal
returns "0.8648" 但作为一个字符串(varchar)所以它 returns '"0.8648"'
这个 CAST(JSON_EXTRACT(price_details, "$.shipping.price") AS FLOAT) as caast
returns 0.8648 所以没问题...
这个 select cast('"0.8648"' as float)
returns 0 和你的结果一样...
您不能将带双引号的值转换为浮点数。
当您合并浮点值和等于该浮点值的 0 时,您将得到一个结果。
我相信这解释了它?
也许除此之外我还应该 ask/say 这个“098”和这个“098”不一样吗?
您使用了错误的 JSON 函数。
JSON_EXTRACT()
return在该路径找到了一个 JSON 对象。这就是为什么在您的 fiddle 中您仍然看到双引号。
您想 return 来自特定路径的标量值。所以,使用 JSON_VALUE()
SELECT
item_id,
JSON_VALUE(price_details, "$.shipping.price") AS shipprice,
CAST(COALESCE(JSON_VALUE(price_details, "$.shipping.price"), '0') AS FLOAT) AS shippricecoalfloat,
COALESCE(CAST(JSON_VALUE(price_details, "$.shipping.price") AS FLOAT), 0) AS shippricefloatcoal
FROM `item`
WHERE order_id = 109517;
此外,数据类型的部分“混乱”是由于您 JSON 将某些值存储为带双引号的字符串,而另一些则存储为数值。我强烈建议不要在 JSON.
中用双引号括起数值
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=d67fa297a5cc4248a06750d71581c022
- 添加了额外的表达式来显示如果将浮点数与整数合并,而不是将浮点数与浮点数合并会发生什么
我有一个奇怪的问题:在 table 的 JSON 列中有一个价格,以下语句给出不同的结果,但它们应该给出相同的结果:
CAST(COALESCE(JSON_EXTRACT(item.price_details, "$.shipping.price"), 0) AS FLOAT) AS shippricecoalfloat
COALESCE(CAST(JSON_EXTRACT(item.price_details, "$.shipping.price") AS FLOAT), 0) AS shippricefloatcoal
为了检查我还添加了一个 JSON_EXTRACT(item.price_details, "$.shipping.price") AS shipprice
结果:
MariaDB 版本:mariadb Ver 15.1 Distrib 10.3.31-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
DB Fiddle (I couldn't use the same MariaDB version but it behaves the same anyways apparently)
我相信这是您问题的“解决方案”:
select cast('"0.8648"' as float)
我将尝试解释我的看法...
首先要知道的是:“COALESCE() 具有与参数相同的数据类型。”
这个 COALESCE(JSON_EXTRACT(price_details, "$.shipping.price"), 0) as coal
returns "0.8648" 但作为一个字符串(varchar)所以它 returns '"0.8648"'
这个 CAST(JSON_EXTRACT(price_details, "$.shipping.price") AS FLOAT) as caast
returns 0.8648 所以没问题...
这个 select cast('"0.8648"' as float)
returns 0 和你的结果一样...
您不能将带双引号的值转换为浮点数。 当您合并浮点值和等于该浮点值的 0 时,您将得到一个结果。
我相信这解释了它?
也许除此之外我还应该 ask/say 这个“098”和这个“098”不一样吗?
您使用了错误的 JSON 函数。
JSON_EXTRACT()
return在该路径找到了一个 JSON 对象。这就是为什么在您的 fiddle 中您仍然看到双引号。
您想 return 来自特定路径的标量值。所以,使用 JSON_VALUE()
SELECT
item_id,
JSON_VALUE(price_details, "$.shipping.price") AS shipprice,
CAST(COALESCE(JSON_VALUE(price_details, "$.shipping.price"), '0') AS FLOAT) AS shippricecoalfloat,
COALESCE(CAST(JSON_VALUE(price_details, "$.shipping.price") AS FLOAT), 0) AS shippricefloatcoal
FROM `item`
WHERE order_id = 109517;
此外,数据类型的部分“混乱”是由于您 JSON 将某些值存储为带双引号的字符串,而另一些则存储为数值。我强烈建议不要在 JSON.
中用双引号括起数值https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=d67fa297a5cc4248a06750d71581c022
- 添加了额外的表达式来显示如果将浮点数与整数合并,而不是将浮点数与浮点数合并会发生什么