【问题标题】:How do I sort using two fields?如何使用两个字段进行排序?
【发布时间】:2011-06-12 19:45:36
【问题描述】:

我有一个排序/分组问题,希望有人能补充一些见解。

我们有一个包含发布日期和更新日期的故事表。我正在使用 Django,所以它看起来像这样:

class Story(models.Model):
    pub_date = models.DateTimeField(db_index=True)
    update_date = models.DateTimeField(blank=True, null=True, db_index=True)
    headline = models.CharField(max_length=200)
    ...

我们希望在按天分组的分页页面上显示故事。所以...

Jan 20
    Story 1
    Story 2

Jan 19
    Story 1
    Story 3

挑战在于,如果故事有 update_date,它应该显示两次,一次在 pub_date 日期,一次在 update_day 日期(例如故事 1)。

有成千上万的故事,所以我当然不能在 python 中全部完成,但我不知道在 SQL 中执行此查询的方法。

我现在拥有的是按 -pub_date 对所有内容进行排序,然后获取给定页面上的最大和最小日期范围。然后,我使用 update_date 查询这些日期之间的任何故事,并在 python 中将它们组合和分组。问题是页面上的项目数量是不规则的。

所以我想我的问题是:查询表以获取项目列表并根据两个字段对它们进行排序的最佳方法是什么,如果它在第二个字段中有值,则在查询中复制一个项目,以及然后根据这两个字段排序?

希望这是有道理的......

【问题讨论】:

    标签: python sql django sorting group-by


    【解决方案1】:

    我只能想到“工会”能够做到这一点。

    这是一个示例。虽然 D:

    查询假定您的表名为 stories,并使用 headlinepub_dateupdate_date 列。它还假设未更新的故事在 update_date 列中的值为 null。

    SELECT      headline,
                the_date,
                DAY(the_date) AS the_day
    FROM (
        SELECT      headline,
                    pub_date AS the_date
        FROM        stories
        UNION
        SELECT      headline,
                    update_date AS the_date
        FROM        stories
        WHERE       update_date IS NOT NULL
    ) AS publishedandupdated
    ORDER BY    the_date DESC;
    

    如果要对查询添加限制,则应在“order by”子句之后最后完成。

    【讨论】:

    • 虽然,您可能应该使用“union all”。不是因为它改变了返回的结果(它将完全相同),而是因为它显然要快得多。这可能是因为它没有尝试进行任何“不同”检查。我刚刚读到有人以比 union 快 3.5 倍的速度对 union 进行基准测试。
    【解决方案2】:

    您的问题与我的问题相似。我从 Facebook 墙上阅读了一些项目。我有两个日期,一个关于项目创建(用户发布项目),一个关于项目检索(我从 Facebook 阅读该项目)。我想显示今天发布或检索到的项目。

    SELECT link,time FROM homeWallItems WHERE 
    DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= created 
    OR
    DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= time
    group by time LIMIT 0,30
    

    编辑:我对这句话过于乐观了:这是错误的。

    在这段代码中,而不是 CURDATE(), 如果您使用time,那么它应该可以工作 你。

    【讨论】:

      【解决方案3】:

      对列名进行一些假设,您需要 UNION ALL 来保留两个部分的重复项。

          select headline, actualdate=pub_date
          from story
          where pub_date between /mindate/ and /maxdate/
      union all
          select headline, actualdate=update_date
          from story
          where update_date between /mindate/ and /maxdate/
      order by actualdate
      
      • 虚拟字段 actualdate 用于将 pub_date / update_date 作为单列进行匹配,以便对其进行排序。
      • 联合语句中的 ORDER BY 在联合完成后应用,因此它只需要出现一次。
      • 日期范围的过滤器应用于联合的每个部分,以减小工作表大小(在应用过滤器之前,它不应该不必要地拉入所有数据)

      【讨论】:

      • 这仍然会导致每页的项目数量无法预测。据我了解,这是旧解决方案导致的不良行为,其中日期范围用于新编写和更新的故事。
      • 不需要在select语句中允许吗?
      • @John - 不,因为它是根据任一分支上的范围获取的。如果它没有 pub_date,它不应该在那里,对于 update_date 也是如此。请记住,工会的每个部分都为整体贡献了independently,因此将显示带有pub in range,update=null 的记录
      猜你喜欢
      • 2016-05-03
      • 2019-03-11
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 2019-06-28
      相关资源
      最近更新 更多