嵌套SQL Server查询最大日期

时间:2013-01-31 20:55:22

标签: sql sql-server tsql

女士和男士,

我需要编写一个从视图中抓取数据的查询,但我不确定如何解决这个问题。问题是确实没有密钥,我关注的是两个字段,它们将控制我需要检索的行。

视图看起来像这样:

Category   columna   columnb   uploaddate 
-----------------------------------------------------
   a        value     value    1/30/2013 04:04:04:000 
   a        value     value    1/29/2013 04:04:04:000 
   b        value     value    1/28/2013 01:23:04:000 
   b        value     value    1/30/2013 04:04:04:000 
   b        value     value    1/30/2013 04:04:04:000 
   c        value     value    1/30/2013 01:01:01:000 
   c        value     value    1/30/2013 01:01:01:000 

我需要检索的是每个唯一类别和最新uploaddate的所有行。因此,在上面的示例中,我将为类别a获得1行,其中包含最新的uploaddate。类别b将有2行,具有1/30/2013日期。类别c也有两行。

我还需要比较上传日期,而不是时间。因为加载可能需要几秒钟。我试图使用最大日期,但它只会占用第二个时间。

任何指导/想法都会很棒。

谢谢!

编辑:

这是我到目前为止所投入的内容,我认为它很接近,但它还没有工作,我怀疑这是最有效的方法。

select 
    * 
from 
    VIEW c 
    INNER JOIN 
    ( 
        SELECT 
            Category, 
            MAX(CONVERT(DateTime, Convert(VarChar, UploadDate, 101))) as maxuploaddate  
        FROM 
            View 
        GROUP BY 
            Category, 
            UploadDate 
    ) temp ON temp.Category = c.Category AND CONVERT(VarChar, UploadDate, 101) = temp.maxuploaddate 

问题在于嵌套的选定语句,因为它仍然抓取了类别和上载日期的所有组合。有没有办法在Category和UploadDate上做一个独特的方法,只是获得最新的组合?

再次感谢

3 个答案:

答案 0 :(得分:1)

如果要对最近的日期执行此操作,则需要先转换为日期。在SQL Server语法中:

select *
from (select category, columna, columnb, uploaddate,
             rank() over ( partition by category order by cast(uploaddate as date) desc) as seqnum
      from view
     ) v
where seqnum = 1

在Oracle语法中:

select *
from (select category, columna, columnb, uploaddate,
             rank() over ( partition by category order by to_char(uploaddate, 'YYYY-MM-DD') desc) as seqnum
      from view
     ) v
where seqnum = 1

由于您需要关联,因此使用rank()代替row_number()

答案 1 :(得分:1)

你的查询很接近,你在组中有错误。我也摆脱了日期转换;日期比较工作正常。

select 
    * 
from 
    VIEW c 
    INNER JOIN 
    ( 
        SELECT 
            Category, 
            MAX(UploadDate) as maxuploaddate  
        FROM 
            View 
        GROUP BY 
            Category
    ) temp ON temp.Category = c.Category AND UploadDate = temp.maxuploaddate 

答案 2 :(得分:0)

在Oracle中,您可以使用Rank()来实现此目的。如果符合相同的条件,Rank()会创建重复的数字。

编辑:您可以使用Trunc()来“修剪”上传日期的时间。

select *
from (select category, columna, columnb, uploaddate,
      rank() over ( partition by category order by trunc(uploaddate) desc) rank
      from view)
where rank = 1

还存在Dense_Rank(),不会创建重复的数字。所以这不适用于此。有关差异的详细信息,请参阅this question