在mysql数据库中,价格的存储方式如下:
98.06K 97.44K 929.14K 91.87K 2.66M 146.64K 14.29K
当我尝试对price asc或price desc排序时,它会返回意外的结果。请建议我如何排序价格时,价格是在10k,20m,1.6b我想要结果
14.29K 91.87K 97.44K 98.06K 146.64K 929.14K 2.66M
hxzsmxv21#
问题在于您的数据模型。我知道2.66m不一定就是2660000,这就是为什么你不想存储整数,而是存储'2.66m'来表示精度。但是,这是两条信息:值和精度,因此请使用两列:
mytable value | unit -------+----- 98.06 | K 97.44 | K 929.14 | K 91.87 | K 2.66 | M 146.64 | K 14.29 | K
以及查找表:
units unit | factor -----+-------- K | 1000 M | 1000000
可能的查询是:
select * from mytable join units using (unit) order by mytable.value * units.factor;
您可能需要扩展 ORDER BY 从句
ORDER BY
order by mytable.value * units.factor, units.factor;
或者用四舍五入或其他方法来考虑两个看似相等的值的精度。
s8vozzvw2#
虽然不可取,但也有可能:https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=0a837287c7646823fa6657706f9ae634
SELECT * , CAST(LEFT(price, LENGTH(price) - 1) AS DECIMAL(10,2)) AS value , RIGHT(price, 1) AS unit , CASE RIGHT(price,1) WHEN 'K' THEN 1000 WHEN 'M' THEN 1000000 ELSE 1 END AS amount FROM test1 ORDER BY amount, value;
为什么不可取?正如dbfiddle中的解释所示,这个查询使用filesort进行排序,这不是很快。如果您的数据中没有太多的行,这应该是没有问题的。
jvlzgdj93#
mysql在将字符串转换为数字时忽略尾随的非数字。这将返回正确的价格:
price * case right(price,1) when 'K' then 1000 when 'M' then 1000000 else 1 end
当然,您可以按此订购,但最好在加载时应用它,并将价格存储在数字列中。
3条答案
按热度按时间hxzsmxv21#
问题在于您的数据模型。我知道2.66m不一定就是2660000,这就是为什么你不想存储整数,而是存储'2.66m'来表示精度。但是,这是两条信息:值和精度,因此请使用两列:
以及查找表:
可能的查询是:
您可能需要扩展
ORDER BY
从句或者用四舍五入或其他方法来考虑两个看似相等的值的精度。
s8vozzvw2#
虽然不可取,但也有可能:
https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=0a837287c7646823fa6657706f9ae634
为什么不可取?正如dbfiddle中的解释所示,这个查询使用filesort进行排序,这不是很快。如果您的数据中没有太多的行,这应该是没有问题的。
jvlzgdj93#
mysql在将字符串转换为数字时忽略尾随的非数字。这将返回正确的价格:
当然,您可以按此订购,但最好在加载时应用它,并将价格存储在数字列中。