Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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
如何以某种方式对这些SQL结果进行排序?_Sql_Postgresql_Sqlalchemy - Fatal编程技术网

如何以某种方式对这些SQL结果进行排序?

如何以某种方式对这些SQL结果进行排序?,sql,postgresql,sqlalchemy,Sql,Postgresql,Sqlalchemy,我正在制作一款活动日历应用程序。用户主页上显示了两种类型的事件: 附近活动-计划日期在未来3天内或过去1小时内的活动 正常事件-没有计划日期或计划日期超过3天的事件 这是事件表:id、用户id、内容、发生时间、创建时间 目前,我正在显示这些按日期排序的事件,创建这些事件是为了首先显示新添加的内容 我想要的是先显示所有附近的事件并按计划日期排序,然后显示正常事件并按创建日期排序。我认为这有助于更好的用户体验,但我不知道如何去做 更新 最后是这个查询,它是几个答案的组合 orderbycoalesc

我正在制作一款活动日历应用程序。用户主页上显示了两种类型的事件:

  • 附近活动-计划日期在未来3天内或过去1小时内的活动
  • 正常事件-没有计划日期或计划日期超过3天的事件
  • 这是事件表:
    id、用户id、内容、发生时间、创建时间

    目前,我正在显示这些按日期排序的事件,创建这些事件是为了首先显示新添加的内容

    我想要的是先显示所有附近的事件并按计划日期排序,然后显示正常事件并按创建日期排序。我认为这有助于更好的用户体验,但我不知道如何去做

    更新

    最后是这个查询,它是几个答案的组合


    orderbycoalesce(发生在:min\u时间和发生在<:max\u时间,0)DESC、发生在ASC、创建于
    orderby
    子句可以包含任意逻辑,而不仅仅是字段名,因此,在伪代码中,您可以

    SELECT ...
    ...
    ORDER BY (date_diff(occurs_at, now) <= '3 days'), occurs_at DESC, created_at DESC
    
    选择。。。
    ...
    
    ORDER BY(date_diff(occurs_at,now)我将通过一个字段来扩展SELECT子句,确定它是否在“附近”(在时间,而不是地点)

    选择
    id、用户id、内容、发生时间、创建时间、,
    
    case when date_diff(d,occurs_at,now)正如@MarcB所提到的,您可以通过一个表达式进行排序,尽管对于PostgreSQL,该表达式看起来有些不同

    SELECT * FROM Events
    ORDER BY CASE WHEN (occurs_at - '3 days'::interval) < CURRENT_TIMESTAMP 
             THEN occurs_at
             ELSE '9999-01-01'::timestamp
             END, created_at;
    
    从事件中选择*
    按案例排序(发生时间为-'3天::间隔)<当前时间戳
    然后发生在
    ELSE“9999-01-01”::时间戳
    结束,创建于;
    

    请注意,“9999-01-01”在某种程度上是一个任意选择的日期,如果有人知道“maxdate”的PostgreSQL常量,我会感兴趣:)

    Verbose格式 更容易解释/理解

    WITH x AS (
       SELECT *
            , COALESCE(occurs_at <= (now() + interval '3 days'), FALSE) AS nearby
       FROM   events
       WHERE  occurs_at >= now() - interval '1 hour' -- exclude older events
          OR  occurs_at IS NULL
       )      -- CTE is not strictly necessary, just to make ORDER BY clearer
    SELECT *
    FROM   x
    ORDER  BY
           nearby DESC
         , CASE WHEN nearby THEN occurs_at ELSE created_at END
    
    如果可以避免,就不要这样做。它迫使Postgres为每一行计算一个值,并使普通索引无法使用。更多信息在此

    简单版本 短一点,快一点

    SELECT *
    FROM   events
    WHERE  occurs_at >= now() - interval '1h'
       OR  occurs_at IS NULL
    ORDER  BY
           COALESCE( occurs_at <= (now()::date + 3), FALSE) DESC
         , CASE WHEN occurs_at <= (now()::date + 3)
                THEN occurs_at ELSE created_at END;
    
    选择*
    从事件中
    其中发生在>=now()处-间隔“1h”
    或在为空时发生
    订购人
    
    合并(发生在您使用的数据库管理系统中?MySQL?SQL Server?PostgreSQL,通过SQLAlchemy的方式。您可以添加假排序列来实现这一点(Beth的回答)。但在检索事件后,您可以很容易地在内存中重新排列SA查询的结果。Postgres为您准备了一些东西。:)。在v8.3之前,这些仅适用于类型
    时间戳
    。从v8.4开始,它们也为日期工作。但是我不认为我们需要在这个例子中使用
    无限
    (以及更高!)。顺便说一句,+1提供一个工作的SQLFIDLE。我我想你错过了过去的事件和没有时间表的事件。我的回答中有详细内容。
    date_diff(d,occurs_at, now) <= 3  -- date_diff is also tSQL, not Postgres
    
    SELECT *
    FROM   events
    WHERE  occurs_at >= now() - interval '1h'
       OR  occurs_at IS NULL
    ORDER  BY
           COALESCE( occurs_at <= (now()::date + 3), FALSE) DESC
         , CASE WHEN occurs_at <= (now()::date + 3)
                THEN occurs_at ELSE created_at END;