Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server-选择所有最热门的小时记录_Sql_Sql Server - Fatal编程技术网

SQL Server-选择所有最热门的小时记录

SQL Server-选择所有最热门的小时记录,sql,sql-server,Sql,Sql Server,我有一个很大的表,每秒钟创建一次记录,只想选择在过去2个月内每小时顶部创建的记录。因此,在过去60天中,我们每天都会得到24条选定的记录 表结构为Dateandtime、Value1、Value2等 非常感谢您可以按日期部分castcol1作为日期和小时部分dateparthh,col1分组。然后选择每小时的最短日期,并根据该日期进行筛选: select * from YourTable yt join ( select min(dateandtime) as d

我有一个很大的表,每秒钟创建一次记录,只想选择在过去2个月内每小时顶部创建的记录。因此,在过去60天中,我们每天都会得到24条选定的记录

表结构为Dateandtime、Value1、Value2等

非常感谢

您可以按日期部分castcol1作为日期和小时部分dateparthh,col1分组。然后选择每小时的最短日期,并根据该日期进行筛选:

select  *
from    YourTable yt
join    (
        select  min(dateandtime) as dt
        from    YourTable
        where   datediff(day, dateandtime, getdate()) <= 60
        group by
                cast(dateandtime as date)
        ,       datepart(hh, dateandtime)
        ) filter
on      filter.dt = yt.dateandtime

您可以为此使用窗口功能:

select dateandtime, val1, val2, . . .
from (select t.*,
             row_number() over (partition by cast(dateandtime as date), hour(dateandtime)
                                order by dateandtime
                               ) as seqnum
      from t
     ) t
where seqnum = 1
函数row_number为partition子句定义的每个组分配一个序列号,在本例中为每天的每个小时。在该组中,它按dateandtime值排序,因此最接近小时顶端的一个值为1。外部查询只为每个组选择这一条记录

您可能需要一个附加的筛选子句来获取过去60天内的记录。在子查询中使用此选项:

where dateandtime >= getdate() - 60
尝试:


为了清楚起见,我可能会使用一种基于CTE的两步方法,这种方法适用于SQL Server 2005和更新版本-您没有明确指定正在使用哪个版本的SQL Server,所以我希望您不再使用像2000这样的古老版本:


另外:我不确定你所说的“小时顶部”到底是什么意思——即在每小时开始时创建的行,例如04:00:00——或者更确切地说,是在该小时的时间跨度内创建的最后一行?如果您是指每小时的第一个,那么您需要将ORDER BY DateAndTime DESC更改为ORDER BY DateAndTime ASC,您可以将选项与EXISTS运算符一起使用

SELECT *
FROM dbo.tableName t 
WHERE t.DateAndTime >= @YourDateCondition
  AND EXISTS (
              SELECT 1
              FROM dbo.tableName t2
              WHERE t2.Dateandtime >= DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime), 0)
                      AND t2.Dateandtime < DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime)+1, 0)
              HAVING MAX(t2.Dateandtime) = t.Dateandtime
              )

这帮我度过了最紧张的时刻。任何以:00:00结尾的内容

WHERE (CAST(DATETIME as VARCHAR(19))) LIKE '%:00:00'

清楚地向我们展示您在每个小时的最佳时段尝试了什么,例如“2013-05-11 09:00:00.000”,而不是“2013-05-11 09:00:01.000”等等。您想要的精度级别将有助于确定哪些时间元素是有效的标准。这似乎很危险,因为它假设所有记录都是,在给定的一秒钟内记录下每一秒,并且没有重复。@GordonLinoff:的确-这是我对问题的解释,问题的每一秒都有记录。对后者做得很好。这是一个很好的修剪解决方案。
-- define a "base" CTE to get the hour component of your "DateAndTime" 
-- column and make it accessible under its own name
;WITH BaseCTE AS
(
    SELECT  
        ID, DateAndTime,
        Value1, Value2, 
        HourPart = DATEPART(HOUR, DateAndTime)
    FROM dbo.YourTable
    WHERE DateAndTime >= @SomeThresholdDateHere
), 
-- define a second CTE which "partitions" the data by this "HourPart",
-- and number all rows for each partition starting at 1. So each "last"
-- event for each hour is the one with the RN = 1 value
HourlyCTE AS 
(
    SELECT ID, DateAndTime, Value1, Value2, 
        RN = ROW_NUMBER() OVER(PARTITION BY HourPart ORDER BY DateAndTime DESC)
    FROM BaseCTE
)
SELECT *
FROM HourlyCTE
WHERE RN=1
SELECT *
FROM dbo.tableName t 
WHERE t.DateAndTime >= @YourDateCondition
  AND EXISTS (
              SELECT 1
              FROM dbo.tableName t2
              WHERE t2.Dateandtime >= DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime), 0)
                      AND t2.Dateandtime < DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime)+1, 0)
              HAVING MAX(t2.Dateandtime) = t.Dateandtime
              )
SELECT *
FROM dbo.test83 t CROSS APPLY (
                               SELECT 1
                               FROM dbo.test83 t2
                               WHERE t2.Dateandtime >= DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime), 0)
                                     AND t2.Dateandtime < DATEADD(HOUR, DATEDIFF(HOUR, 0, t.Dateandtime)+1, 0)
                               HAVING  MAX(t2.Dateandtime) = t.Dateandtime                            
                               ) o(IsMatch)
WHERE t.DateAndTime >= @YourDateCondition 
CREATE INDEX x ON dbo.test83(DateAndTime) INCLUDE(Value1, Value2)
WHERE (CAST(DATETIME as VARCHAR(19))) LIKE '%:00:00'