2010-05-14 216 views
0

把这个简单的查询:GROUP BY的日期,与日期排序

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

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

干杯

回答

1

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

在其他数据库(postgresql,oracle,db2)中,有一些窗口函数允许在单个select(即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。

+0

谢谢。我能够用一个内部查询来做到这一点,但是想知道是否有办法做到这一点。你回答了这个问题。 :) – 2010-05-14 11:18:57

+0

我希望有,我想能够生成一个密集的列列,然后只是选择其中的dense_rank是1的行。哦,至少MySql是快速的。干杯。 – Gennadiy 2010-05-14 11:21:39

0

我会重写查询是这样的:

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

如果完全由(即你正在使用您没有显示我们的聚合函数)需要组只是做:

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 
+0

这两者都不起作用。 第一个将返回同一日期的行(我只希望每个日期有一行,因此分组依次),第二个不能保证选择每个日期的最早日期。 – 2010-05-14 11:10:22