【问题标题】:GROUP BY a date, with ordering by date按日期分组,按日期排序
【发布时间】:2011-02-19 11:40:56
【问题描述】:

采取这个简单的查询:

SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay
FROM someTable
GROUP BY formatterDay

这将从每个日期只有 1 行的表中选择行。
如何确保每个日期选择的行是该日期的最早行,而不在 FROM 中执行有序子查询?

干杯

【问题讨论】:

    标签: mysql group-by sql-order-by


    【解决方案1】:

    如果您使用的是 MySQL,则无法在单个选择中执行您想要的操作。您需要一个内部查询,为每个格式化日期选择最小 ID 和格式化或其他字段。然后再次将其加入父表并选择具有最小 ID 的记录。

    在其他数据库(postgresql、oracle、db2)中,有允许在单个选择中执行此操作的窗口函数(即 DENSE_RANK() OVER ...)。

    这是一个带有内部查询的示例(您可能已经知道):

    SELECT B.formattedDay, A.*
      FROM someTable A
           JOIN 
           (
               SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay,
                      MIN(ID) as firstId
                 FROM someTable I
             GROUP BY 1
           ) B ON (A.ID = B.firstId)
    

    如果需要,将 MIN(ID) 更改为 MIN(someDate) 及其时间戳。如果多个记录可以出现相同的时间戳,您将需要执行两次操作。首先获取每天的最小日期,然后是每个最小日期的最小 ID。

    【讨论】:

    • 谢谢。我可以通过内部查询来做到这一点,但想知道是否有办法在没有内部查询的情况下做到这一点。你回答了那个问题。 :)
    • 我希望有,我想念能够生成密集等级列然后只选择密集等级为 1 的行。哦,好吧,至少 MySql 很快。干杯。
    【解决方案2】:

    我会这样重写你的查询:

    SELECT distinct DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay
      FROM someTable
     ORDER BY DATE_FORMAT(someDate, '%y-%m-%d') 
    

    如果您绝对需要 group by(即您正在使用未向我们显示的聚合函数),只需执行以下操作:

    SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay
      FROM someTable
     GROUP BY DATE_FORMAT(someDate, '%y-%m-%d')
     ORDER BY DATE_FORMAT(someDate, '%y-%m-%d') -- this is redundant, but you can use another column here
    

    【讨论】:

    • 这些都不行。第一个将返回同一日期的行(我只希望每个日期一行,因此分组依据),第二个不保证选择每天的最早日期。
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多