【问题标题】:Peewee: how to do ORDER BY ... NULLS (FIRST|LAST)?Peewee:如何做 ORDER BY ... NULLS (FIRST|LAST)?
【发布时间】:2016-12-30 15:19:34
【问题描述】:

标题几乎概括了它:我想指定空值在我的结果中是首先出现还是最后出现。在我的具体情况下,我想按降序排序最后得到空值,对应于这样的 SQL:

SELECT id, something, something_else
FROM mytable
ORDER BY something DESC NULLS FIRST;

这是 PostgreSQL 语法(这是我在这个项目中使用的)。同样的问题可能适用于其他数据库(尽管我认为 MySQL 不支持该语法,不确定它是否支持该功能)。当然首先有空值是默认的升序(see PostgreSQL docs),所以只有组合 DESC NULLS FIRST 和 ASC NULLS LAST 可能有用...除了方便,MySQL 默认是precisely the opposite.

看来我应该能够做到以下几点:

MyModel.select().order_by(MyModel.something.desc().nulls_first())
MyModel.select().order_by(MyModel.something.desc(nulls_first))

我不是 Python 专家,但我在 Peewee 文档或源代码中找不到任何看起来可以满足我要求的东西。

当然,可能有很多解决方法。以下是我发现或想到的,按实用性递减顺序(对我而言):

  • 使用原始 SQL(这在我的情况下实际上可以工作,但如果我以后需要对象就不是很好)
  • 通过按其他东西排序来伪造它(例如一个函数,我也不知道如何处理 Peewee,或者按照 this 的行添加派生列)
  • 可能使用 UNION 来组合具有 WHERE ?? 的查询有 WHERE 的不是 NULL 吗? IS NULL ...但这在几个方面似乎存在问题,例如我不知道 Peewee 是否也可以做到这一点,而且无论如何最好还是对整个事情执行 ORDER BY
  • 运行两个单独的查询并将它们的结果集放在 Python 中...再次,我认为这听起来很麻烦(额外开销,需要 1 个事务来保证数据完整性)
  • 重新设计架构,这样我就不必按可能为 null 的内容进行排序(也许有一天...)

那么:Peewee 可以做到这一点吗?如果没有,有没有比我想象的更好的解决方法?

【问题讨论】:

    标签: postgresql peewee


    【解决方案1】:

    说实话,我认为你把问题复杂化了。

    从 Peewee 3.x 开始,您可以指定对 null 的处理:

    MyModel.select().order_by(MyModel.something.desc(nulls='LAST'))
    

    您还可以使用 case 语句创建一个包含 1 或 0 的别名列,以指示您要排序的列是否为空。然后按顺序使用该别名。

    【讨论】:

    • 谢谢,没想到我能做到。供将来参考:第二个选项在进行连接时很棘手(就像我一样),因为如果您需要按通用列名排序,您必须知道正在使用什么表别名。第一个选项效果很好(在我意识到我不应该将额外的列引用放在同一个子句中之后!)。
    • 更新:使用新版本的 peewee,Clause() 不再可用。但在这种情况下,现在有更好的方法:.order_by(MyModel.field.desc(nulls="LAST"))。 (适用于 peewee 3.5.0 版;上面的答案是针对 2.x 的……不确定它什么时候发生了变化。)
    猜你喜欢
    • 2011-04-10
    • 2014-09-05
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多