C# 查找每小时创建的最大行数?

C# 查找每小时创建的最大行数?,c#,linq,sql-server-2005,linq-to-sql,C#,Linq,Sql Server 2005,Linq To Sql,我有一个表来存储产品评论,如下所示: Id -int ProductId -int Timestamp -datetime Comments -text SELECT DAY(TimeStamp), MONTH(TimeStamp), YEAR(TimeStamp), DATEPART(HOUR, TimeStamp), COUNT(*) FROM dbo.Products GROUP BY DAY(TimeStamp), MONTH(TimeS

我有一个表来存储产品评论,如下所示:

Id -int
ProductId -int
Timestamp -datetime
Comments -text
SELECT
    DAY(TimeStamp), MONTH(TimeStamp), YEAR(TimeStamp),
    DATEPART(HOUR, TimeStamp),
    COUNT(*)
FROM    
    dbo.Products
GROUP BY
    DAY(TimeStamp), MONTH(TimeStamp), YEAR(TimeStamp),
    DATEPART(HOUR, TimeStamp)
ORDER BY
    COUNT(*) DESC
是否有一种简单的方法来计算和确定产品在任何60分钟时间内收到的评论的比率?即:Widget1每小时的最大评论数为55


使用sql05。

另一个选项是使用SQL DATEPART函数,如下所示:

Id -int
ProductId -int
Timestamp -datetime
Comments -text
SELECT
    DAY(TimeStamp), MONTH(TimeStamp), YEAR(TimeStamp),
    DATEPART(HOUR, TimeStamp),
    COUNT(*)
FROM    
    dbo.Products
GROUP BY
    DAY(TimeStamp), MONTH(TimeStamp), YEAR(TimeStamp),
    DATEPART(HOUR, TimeStamp)
ORDER BY
    COUNT(*) DESC
这不仅为您提供了任何给定小时的最大视图数,还提供了按频率排序的所有视图数。请注意:除了RexM的解决方案之外,这是基于时间戳的小时部分-因此,如果您在7:59有很多视图,而在8:01有另一个突发视图,在我的解决方案中,这些视图不会一起显示,因为一个是小时=7,另一个是小时=8


如果您需要任何60分钟的时间跨度方法,请使用RexM的基本思想DATEDIFF with minutes如果您使用的是一个设定的60分钟时间段,例如从现在开始的最后60分钟,那么这相当简单:

SELECT TOP 1
    PR.ProductID,
    COUNT(*)
FROM ProductReviews PR
WHERE PR.Timestamp BETWEEN DATEADD( minute, -60, GETDATE() ) AND GETDATE()
GROUP BY PR.ProductID
ORDER BY COUNT(*) DESC

如果你想要任何60分钟的间隔,那么它会变得更复杂

我不知道有什么简单的方法来计算这个指标,但希望这会有所帮助。如果没有某种SQL游标,我将生成一个可能间隔的SQL表,带有开始和结束时间戳2009-09-02T00:00到2009-09-02T00:59、2009-09-02T00:01到2009-09-02T01:00等,然后使用LINQ到SQL交叉连接:

var rates = from r in db.Reviews
            from i in db.Intervals
            where i.Begin <= r.Timestamp && r.Timestamp <= i.End
            group r by i.Begin into reviews
            select reviews.Count();
var maxRate = rates.Max();
我还没有试过这个代码,但它应该可以让你开始。您可以通过限制检查最后7天、30天等的时间间隔来提高性能,或者减少从四分之一小时开始的间隔时间。

如果您希望哪种产品在dateX和dateY之间的60分钟内获得最多的评论,那么它会变得更复杂一些

一种思考方法是,在接下来的60分钟内,对于该时间段内的每次评审,有多少其他评审针对相同的产品ID。一旦有了这种逻辑,查询就会变得更清晰:

SELECT TOP 1
    PR.ProductID,
    -- start of 60 minute block
    PR.Timestamp,
    ReviewCount = (
        SELECT COUNT(*)
        FROM ProductReviews PR1
        -- from parent time
        WHERE PR1.Timestamp >= PR.Timestamp
        -- until 60 mins later
        AND PR1.Timestamp <= DATEADD( minute, 60, PR.Timestamp )
        -- that matches ProductID
        AND PR1.ProductID = PR.ProductID
    )
FROM ProductReviews PR
-- in the last 24 hours
WHERE PR.Timestamp > ( GETDATE() - 1 )
ORDER BY ReviewCount DESC

如果你对固定窗口的时间感到满意,我可能会考虑通过使用触发器来做得更聪明一点。触发器将插入/更新到“日志”表中,并根据当前时间区分插入和更新


您可以将其与任何其他方法结合使用,这将添加一个不错的缓存层。

不错的选择。在我扫除SQL大脑中的灰尘之后,我意识到OP希望LINQ使用SQL,而不是SQL。还明确地说“任意60分钟的时间跨度”除了标记之外,没有看到任何关于Linq到SQL的提及,是的,我注意到了任意60分钟的跨度——尽管这有点棘手。也许这种方法可以-我们将拭目以待-直到OP打电话:-最好是寻找一个滚动60分钟的窗口,但可能必须解决固定的时间。