排序不适用于字符串数值

问题描述 投票:0回答:4

我有一个文本字段(Django)用于数据库中的数量

amount = models.TextField(null=True, blank=True)

SQL查询

select id, amount from payment order by amount asc;

  id   | amount  |
-------+---------+
 12359 | 1111111 |  ----> entered as "1111111" i.e a string value             
 12360 | 122222  |               
 12342 | 20      |               
 12361 | 222222  |               
 12364 | 2222222 |               
 12362 | 2222222 |               
 12290 | 260.00  |               
 12291 | 260.00  |               
 12292 | 260.00  |               
 12336 | 32      |               
 12363 | 3333333 |               
 12337 | 355     |                
 12331 | 45      |               
 12341 | 740     |             
 12343 | 741     |   

问题 - 订购没有按预期工作。

这是预期的行为吗?

django postgresql django-models sql-order-by
4个回答
0
投票

当您使用字符串时,排序基于基于 ASCII 的系统。 为了缓解此类问题,最好使用

models.DecimalField

更多信息:https://docs.djangoproject.com/en/4.1/ref/models/fields/#decimalfield


0
投票

金额字段应该是数字字段而不是文本字段。然后订购将起作用。

from decimal import Decimal

class Payment(models.Model):
    amount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)

之后请运行migration


0
投票

尝试其中之一:

select * from tab_name order by column_name::integer;
 select * from tab_name order by cast(column_name AS integer);
select * from tab_name order by int8 (column_name);

希望对你有帮助。 但我不明白为什么要在文本或 varchar 中保留整数。稍后这会给你带来很多问题,空间和速度。


0
投票

您可以

Cast
值作为 Float 字段并按它排序:

MyModel.objects.annotate(as_float=Cast('amount', FloatField())).order_by('as_float')

但是,正如@IqbalHussain 在他的回答中提到的那样,最好更改模型。

© www.soinside.com 2019 - 2024. All rights reserved.