【问题标题】:How to compare two numbers as strings in MySQL?如何在 MySQL 中将两个数字作为字符串进行比较?
【发布时间】:2017-01-28 18:42:06
【问题描述】:

我想在 MySQL 中将两个字符串作为数字进行比较。我的表中有以下数据:

0,15 kg 0,52 kg 0,68 kg 1,24 kg

现在我想将一个字符串与该数据进行比较。我尝试的是这样的:

SELECT * FROM `foobar` WHERE weight+0.0 <= '0,7 kg'

由于 MySQL 似乎不将逗号理解为小数分隔符,因此我尝试将其替换为点:

SELECT * FROM `foobar` WHERE REPLACE(weight+0.0,',','.') <= REPLACE('0,7 kg',',','.')

但是,我总是得到奇怪的结果,包括大于 0.7 的数字。奇怪的是,当我尝试订购重量列时,订购是正确的!

【问题讨论】:

  • 正确存储数据
  • 当然,你应该把它分开,就像草莓提到的那样。但是mysql能够对其进行排序。例如where foo &gt; '0,52' 有效。
  • 是的,我知道它应该以不同的方式存储。如果数字后面有“kg”,则排序无法正常工作。
  • @phpheini 也这么认为。但它确实有效:i.imgur.com/ZNkcdM6.png
  • 使用无符号十进制 5,2 列类型来存储该数据,您可以根据需要轻松地将 kg 添加到它的显示上

标签: php mysql compare


【解决方案1】:

使用构造 CAST(val AS DECIMAL(10,2))

SELECT * FROM `foobar `
WHERE CAST(REPLACE(weight,',','.') AS DECIMAL(10,2)) <= CAST(REPLACE('0,7 kg',',','.') AS DECIMAL(10,2));

查询已经过测试并给出正确的结果。

此解决方案不能使用索引。更好的方法是查询填充了计算数据的临时表。或者,您可以将索引 DECIMAL 列 weight_dec 添加到此表并使用触发器根据权重填充数据。然后使用 weight_dec 查询。

【讨论】:

  • 太棒了,谢谢!您知道这两个操作是否会消耗大量性能,还是可以在生产中使用它?
  • 我认为这是一些成本,但你说你坚持这个数据库设计。不要忘记标记为答案:)
  • @phpheini any 查询其中列值用作函数的参数或与 WHERE 子句中的操作符(例如 weight + 0)结合使用大规模的严重性能损失,因为它强制表扫描针对每一行评估函数,从而阻止在任何 RDBMS(不仅仅是 MySQL)中使用相关列上的任何索引。你永远不应该写这样的查询。但是,如果您正在执行与此类似的操作,那么此查询的性能不会比其他查询差。你需要修复你的设计。在那之前,这是正确的解决方案。
  • 阅读 sargability 以了解有关该主题的更多信息...包括What makes a SQL statement sargable? 需要明确的是,CAST()REPLACE() 本身实际上产生的影响微不足道,以至于它可以被忽略。问题是在谓词中使用 any 函数会破坏可搜索性。
  • 如果您的表不经常更改,您可以创建其他表并使用来自其他表的计算数据填充它。这是生成报告和统计信息的常见做法。它使您能够在 WHERE 子句中使用计算列。因此,您可以填充 Decimal 列并对其执行快速查询。
猜你喜欢
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多