如何选择每天的最新时间戳

时间:2017-03-10 11:58:17

标签: sql sql-server tsql greatest-n-per-group

我每小时都有一个报告,显示数据库的磁盘空间使用情况。 然后通过电子邮件发送。

我想将其更改为显示最后一个snapshot_date的统计信息

数据如下

Day Date    Time    WeekNo  Data_Size_MB    Used_Data_MB

Friday  10-Mar-17   11:00   11  118784  92670.33

Friday  10-Mar-17   10:00   11  118784  92653.96

Friday  10-Mar-17   09:00   11  118784  92641.16

Friday  10-Mar-17   08:00   11  118784  92636.39

Friday  10-Mar-17   07:00   11  118784  92584.42

Thursday    09-Mar-17   23:00   11  118784  92586.25

Thursday    09-Mar-17   22:00   11  118784  92586.06

Thursday    09-Mar-17   21:00   11  118784  92585.85

下面的sql

select  Day = datename(dw,snapshot_Date),
        Date = convert(varchar(19), Snapshot_Date, 106),
        Time = substring(CONVERT(VARCHAR, snapshot_Date, 108),0,6),
        WeekNo = DATEPART(week, snapshot_Date),
        Data_Size_MB = Data_Size_MB,
        Used_Data_MB = Used_Data_MB,
        Data_Full_Pcnt = Data_Full_Pcnt,
        Log_Size_MB = Log_Size_MB,
        Free_Log_MB = Free_Log_MB,
        Log_Full_Pcnt = Log_Full_Pcnt,  
        snapshot_Date            
from Ideal_Risk.dbo.Sybase_Disk_Space
where database_name='IDEAL'
order by snapshot_date desc

但我希望它返回

Day Date    Time    WeekNo  Data_Size_MB    Used_Data_MB

Friday  10-Mar-17   11:00   11  118784  92670.33

Thursday    09-Mar-17   23:00   11  118784  92586.25

即每天的最后一张快照

nb:我已经删除了数据中返回的一些列

4 个答案:

答案 0 :(得分:0)

解决方案是创建一个中间表,您可以在其中为每个日期添加一个rownumber。然后,您只能选择每个日期的第一行。

select *, 
       ROW_NUMBER() OVER(PARTITION BY Date ORDER BY Date DESC) AS rownum 
into #some_temp
from Ideal_Risk.dbo.Sybase_Disk_Space
where database_name='IDEAL'

select  Day = datename(dw,snapshot_Date),
    Date = convert(varchar(19), Snapshot_Date, 106),
    Time = substring(CONVERT(VARCHAR, snapshot_Date, 108),0,6),
    WeekNo = DATEPART(week, snapshot_Date),
    Data_Size_MB = Data_Size_MB,
    Used_Data_MB = Used_Data_MB,
    Data_Full_Pcnt = Data_Full_Pcnt,
    Log_Size_MB = Log_Size_MB,
    Free_Log_MB = Free_Log_MB,
    Log_Full_Pcnt = Log_Full_Pcnt,  
    snapshot_Date            
from #some_temp
where database_name='IDEAL' and rownum = 1

当然你也可以做一个嵌套的from (select ...) b

答案 1 :(得分:0)

您可以像这样使用CTES

with mondayTable as(
select  Day = datename(dw,snapshot_Date),
        Date = convert(varchar(19), Snapshot_Date, 106),
        Time = substring(CONVERT(VARCHAR, snapshot_Date, 108),0,6),
        WeekNo = DATEPART(week, snapshot_Date),
        Data_Size_MB = Data_Size_MB,
        Used_Data_MB = Used_Data_MB,
        Data_Full_Pcnt = Data_Full_Pcnt,
        Log_Size_MB = Log_Size_MB,
        Free_Log_MB = Free_Log_MB,
        Log_Full_Pcnt = Log_Full_Pcnt,  
        snapshot_Date            
from Ideal_Risk.dbo.Sybase_Disk_Space
where database_name='IDEAL' and datename(dw,snapshot_Date) = 'Monday'
order by snapshot_date desc
)

tuesdayTable as(
select  Day = datename(dw,snapshot_Date),
        Date = convert(varchar(19), Snapshot_Date, 106),
        Time = substring(CONVERT(VARCHAR, snapshot_Date, 108),0,6),
        WeekNo = DATEPART(week, snapshot_Date),
        Data_Size_MB = Data_Size_MB,
        Used_Data_MB = Used_Data_MB,
        Data_Full_Pcnt = Data_Full_Pcnt,
        Log_Size_MB = Log_Size_MB,
        Free_Log_MB = Free_Log_MB,
        Log_Full_Pcnt = Log_Full_Pcnt,  
        snapshot_Date            
from Ideal_Risk.dbo.Sybase_Disk_Space
where database_name='IDEAL' and datename(dw,snapshot_Date) = 'Tuesday'
order by snapshot_date desc
)
SELECT  *
FROM    mondayTable
UNION ALL
SELECT  *
FROM    tuesdayTable

答案 2 :(得分:0)

您应该可以使用row_number()

select sds.*
from (select sds.*,
             row_number() over (partition by date order by time desc) as seqnum
      from Ideal_Risk.dbo.Sybase_Disk_Space
      where database_name = 'IDEAL'
     ) sds
where seqnum = 1
order by snapshot_date desc

答案 3 :(得分:0)

我们可以省略使用ROW_NUMBER()函数和每行的编号。

在以下查询中,我正在寻找每天的最大{ accounts(filter: {fieldName: "id", fieldValues: "123", filterType: "in"}) { id } } ,并在CTE(Snapshot_Date)中按日期分组(CAST(Snapshot_Date AS DATE)),然后将结果合并到原始表提取这些日期的记录。

LatestDailySnapshot

注意1 :如果你有一个索引(DECLARE @DatabaseName VARCHAR(50) = 'IDEAL'; WITH LatestDailySnapshot AS ( SELECT MAX(Snapshot_Date) AS Latest_Snapshot_Date FROM Ideal_Risk.dbo.Sybase_Disk_Space WHERE Database_Name = @DatabaseName GROUP BY CAST(Snapshot_Date AS Date) ) SELECT * FROM Ideal_Risk.dbo.Sybase_Disk_Space WHERE Database_Name = @DatabaseName JOIN LatestDailySnapshot ON Latest_Snapshot_Date = Snapshot_Date ORDER BY snapshot_date )会更有效。

注意2 :如果每个(Database_Name, Snapshot_DateDatabase_Name)组合有多个行,则此方法无法正常工作。这意味着以下查询不应返回任何结果:

Snapshot_Date