【问题标题】:Django queryset order_by greater value of two columnsDjango queryset order_by 两列的较大值
【发布时间】:2014-10-26 22:05:03
【问题描述】:

我有以下 Django 模型:

class Entry(models.Model):
      date_entered = models.DateTimeField(auto_now_add=True)
      date_renewed = models.DateTimeField(blank=True,null=True)

在创建 Entry 对象并将 date_renewed 字段设置为 Null 时自动填充 date_enterd。有些条目会更新,有些则不会(这意味着有些条目将设置日期时间,而有些则始终为空)。

我需要按两者中最近的时间对查询集进行排序,因为如果更新旧条目,它应该是查询集中的第一个对象,但是当添加新条目时,更新的条目应该转到第二名。

条目应按如下方式返回:

ID   DateEntered                         DeteRenewed 
55   2014-09-02 13:39:37.698422+00:00    None
45   2014-08-06 00:00:00+00:00           2014-08-31 11:43:05.339902+00:00
54   2014-08-31 00:00:00+00:00           None
43   2014-08-06 00:00:00+00:00           2014-08-30 10:49:51.594024+00:00
51   2014-08-15 00:00:00+00:00           2014-08-29 10:49:51.594024+00:00

我尝试过使用:

qs.extra(select={"sort_order":"COALESC(date_entered,date_renewed)"}, order_by=["-sort_order"])

但这不起作用,因为它选择了第一个非 Null 值。

我在生产中使用 Postgres,在开发中使用 SQLite。如果可能的话,我想坚持使用 Django 的 ORM。

查询集如何按上面指定的顺序排序?

【问题讨论】:

  • 您是否尝试过先按 DateRenewed 排序,然后按 Date Entered 排序?
  • @BurhanKhalid,如果你这样做,我认为所有更新的条目都会首先出现,然后才会出现没有更新日期的条目,即使它们是最近的。 user3138929,一种方法可能是将 DateRenewed 默认为当前日期(如 DateEntered),而不是 null,并按此排序。通过比较 DateRenewed 和 DateEntered,您仍然可以找到没有续订的条目。当然,您将不必要地存储一些(或许多)日期两次。
  • 对不起,双重评论,但这发生在我身上......如果 COALESCE 选择第一个非空值,如果你颠倒它的参数顺序,它不会起作用,先给它 date_renewed ?
  • 问答中的错字。 *COALESCE

标签: sql django django-models django-orm


【解决方案1】:

如果我按照 Paulo Almeida 的指出交换列的顺序,则 COALESCE 会起作用。 Paulo 还正确地指出,支持 Burhan Khalid 的解决方案是行不通的。

解决办法是:

qs.extra(select={"sort_order":"COALESC(date_renewed,date_entered)"}, order_by=["-sort_order"])

【讨论】:

    猜你喜欢
    • 2022-09-28
    • 2011-03-04
    • 1970-01-01
    • 2013-12-05
    • 2018-06-24
    • 1970-01-01
    • 2018-08-12
    • 2018-02-22
    • 1970-01-01
    相关资源
    最近更新 更多