每天选择最接近凌晨4点的1行?

时间:2016-03-03 14:36:15

标签: sql sql-server common-table-expression

我们目前正在处理查询报表,该报表会返回一系列数据。客户已指定他们希望总共收到5行,其中包含前5天的数据(由开始日期和结束日期变量定义)。对于每一天,他们都希望来自最接近凌晨4点的行的数据。

我设法让它工作了一天,但我当然不想仅仅为了获取这些值而联合5个单独的select语句。有没有办法通过CTE实现这一目标?

select top 1 
    'W' as [RecordType]
,   [WellIdentifier]                    as [ProductionPtID]
,   t.Name                              as [Device Name]
,   t.RecordDate --convert(varchar, t.RecordDate, 112) as [RecordDate]
,   TubingPressure                      as [Tubing Pressure]
,   CasingPressure                      as [Casing Pressure]
from #tTempData t
Where cast (t.recorddate as time) = '04:00:00.000'
or datediff (hh,'04:00:00.000',cast (t.recorddate as time)) < -1.2
order by Name, RecordDate desc 

4 个答案:

答案 0 :(得分:4)

假设#tTempData仅包含前5天的记录

SELECT *
FROM
(
    SELECT *, rn = row_number() over 
                   ( 
                      partition by convert(date, recorddate)
                      order by ABS ( datediff(minute, convert(time, recorddate) , '04:00' )
                   )
    FROM   #tTempData

)
WHERE rn = 1

答案 1 :(得分:3)

您可以像这样使用row_number()来获取最接近04:00的前5天

SELECT TOP 5 * FROM (
    select t.* , 
           ROW_NUMBER() OVER(PARTITION BY t.recorddate
                        ORDER BY abs(datediff (minute,'04:00:00.000',cast (t.recorddate as time))) rnk
    from #tTempData t)
WHERE rnk = 1
ORDER BY recorddate DESC

答案 2 :(得分:2)

您可以将row_number()用于此目的:

select t.*
from (select t.*,
             row_number() over (partition by cast(t.recorddate as date)
                                order by abs(datediff(ms, '04:00:00.000',
                                                      cast(t.recorddate as time)
                                                     ))
                               ) seqnum
      from #tTempData t
     ) t
where seqnum = 1;

您可以在子查询中添加适当的where子句,以获取您感兴趣的日期。

答案 3 :(得分:0)

尝试这样的事情:

select 
    'W' as [RecordType]
,   [WellIdentifier]                    as [ProductionPtID]
,   t.Name                              as [Device Name]
,   t.RecordDate --convert(varchar, t.RecordDate, 112) as [RecordDate]
,   TubingPressure                      as [Tubing Pressure]
,   CasingPressure                      as [Casing Pressure]
from #tTempData t
Where exists
(select 1 from #tTempData t1 where
    ABS(datediff (hh,'04:00:00.000',cast (t.recorddate as time))) < 
    ABS(datediff (hh,'04:00:00.000',cast (t1.recorddate as time)))
    and GETDATE(t.RecordDate) = GETDATE(t1.RecordDate)
)dt
and t.RecordDate between YOURDATERANGE
order by Name, RecordDate desc;