我有一个包含每秒创建记录的大表,并且只想选择过去2个月内每小时顶部创建的记录。因此,我们将在过去60天内每天获得24条选定的记录
表结构是Dateandtime,Value1,Value2等
非常感谢
答案 0 :(得分:2)
您可以group by
在日期部分(cast(col1 as date)
)和小时部分(datepart(hh, 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
或者,您可以对仅包含日期和小时的日期格式进行分组。例如,convert(varchar(13), getdate(), 120)
会返回2013-05-11 18
。
...
group by
convert(varchar(13), getdate(), 120)
) filter
...
答案 1 :(得分:2)
为了清楚起见,我可能会使用两步,基于CTE的方法(这适用于SQL Server 2005 和更新 - 你没有明确指出哪个你正在使用的SQL Server的版本,所以我只是希望你不再使用像2000这样的古老版本):
-- 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
另外:我不确定完全你的意思是“每小时” - 在每小时开始时创建的行(例如04:00:00
) - 或者说是在那个小时的时间范围内创建的最后一行?如果您指的是每小时的第一个 - 那么您需要将ORDER BY DateAndTime DESC
更改为ORDER BY DateAndTime ASC
答案 2 :(得分:2)
您可以使用带有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
)
与CROSS APPLY运算符
的OR选项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)
答案 3 :(得分:1)
您可以使用窗口函数:
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
答案 4 :(得分:0)
尝试:
select * from mytable
where datepart(mi, dateandtime)=0 and
datepart(ss, dateandtime)=0 and
datediff(d, dateandtime, getdate()) <=60
答案 5 :(得分:0)
这帮助我获得了最高分。任何以“:00:00”结尾的内容。
WHERE (CAST(DATETIME as VARCHAR(19))) LIKE '%:00:00'