Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 更正在Postgres中使用nil值排序日期和使用AR排序SQLite3时的不同行为_Ruby On Rails_Sqlite_Postgresql_Activerecord_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 更正在Postgres中使用nil值排序日期和使用AR排序SQLite3时的不同行为

Ruby on rails 更正在Postgres中使用nil值排序日期和使用AR排序SQLite3时的不同行为,ruby-on-rails,sqlite,postgresql,activerecord,ruby-on-rails-4,Ruby On Rails,Sqlite,Postgresql,Activerecord,Ruby On Rails 4,我在Rails 4上,在项目模型上有一个开始日期:日期属性。我正在使用ActiveRecord,当存在nil值时,以下请求在Postgres和SQLite上返回不同的结果: User.first.projects.order(begin_date: :desc, end_date: :desc) 在Postgres中,nil值被视为比现有值高的值(因此排在第一位),而在SQLite记录中,nil值排在最后 我是做错了什么,还是这是预期的行为 如何重构上述查询,使其在Postgres和SQLit

我在Rails 4上,在
项目
模型上有一个
开始日期:日期
属性。我正在使用ActiveRecord,当存在
nil
值时,以下请求在Postgres和SQLite上返回不同的结果:

User.first.projects.order(begin_date: :desc, end_date: :desc)
在Postgres中,
nil
值被视为比现有值高的值(因此排在第一位),而在SQLite记录中,
nil
值排在最后

  • 我是做错了什么,还是这是预期的行为

  • 如何重构上述查询,使其在Postgres和SQLite上呈现相同的结果(关于
    nil
    值)


  • 请注意,如果您有强烈的意见认为我应该在所有环境中使用相同的db技术:谢谢您的考虑,但我知道这一点,这个问题与该主题无关。

    由于默认行为在数据库中不同,您需要明确指定
    NULL
    的处理方式

    有几种方法可以做到这一点,但最可移植的方法似乎在和中进行了描述,它使用
    CASE
    语句来显式处理空值

    在您的情况下,它将类似于:

    order('case when begin_date is null then 1 else 0 end,
         begin_date desc, case when end_date is null then 1 else 0 end, end_date desc')
    
    取决于要排序的空值的位置。如果希望先对空值进行排序,则可以交换1和0

    另一种方法是通过将null转换为非null的表达式进行排序。我不确定在这方面,SQL标准是什么,包括
    ISNULL
    NVL
    IFNULL
    COALESCE
    ,甚至不确定这两种标准对sqllite和postgres都是通用的


    讨论Rails中缺乏(以及需要)一种机制来支持这一点,通过
    顺序

    您希望
    null
    s位于哪一端?我更希望它们的排名低于具有现有值的记录。嗯,很有趣。有点伤心。当涉及到按两列排序(即,如果第一列相等,则按第二列排序)时,您可能对我的情况有任何明确的代码建议吗?您也可以使用
    COALESCE(begin_date,X)
    将空值转换为更可预测的值(当然,假设存在合适的
    X
    s)是的,大家都开始在这件小事上遵循标准了。最后因此,您可以在SQLite和PostgreSQL(甚至MySQL)中合并。@muistooshort您是否愿意详细说明在上述场景中使用
    COALESCE
    的实现是什么样子的。聚结的问题也在那里被注意到。