2009-09-02 20 views
2

J'ai une table pour stocker critique sur ce produit comme celui-ci:Recherche du nombre maximum de lignes créées par heure?

Id -int 
ProductId -int 
Timestamp -datetime 
Comments -text 

Est-il un moyen facile de compter et de déterminer le taux d'examens d'un produit a reçu au cours de 60 minutes timespan? c'est à dire. Widget1 avis maximum/heure est 55.

fonctionnant avec sql05.

Répondre

1

Une autre option serait d'utiliser les fonctions de DATEPART SQL comme ceci:

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 

Cela vous donne pas seulement le nombre maximum de vues pour une heure donnée, mais chacun d'entre eux, triés par la fréquence. Rappelez-vous: autre que la solution de RexM, elle est basée sur la partie "heure" de votre "horodatage" - donc si vous avez pas mal de vues à 7h59 et une autre à 8h01, dans ma solution, elles ne le seraient pas t être montré ensemble (puisque l'un est l'heure = 7 et l'autre l'heure = 8).

Si vous avez besoin de l'approche «n'importe quelle période de 60 minutes», utilisez l'idée de base de RexM (DATEDIFF avec les minutes < = 60).

Marc

+0

Belle alternative. J'ai réalisé après avoir fini de brosser la poussière de mon cerveau SQL que l'OP voulait LINQ à SQL, pas SQL.(Il est aussi explicitement dit «n'importe quelle période de 60 minutes») –

+0

Ne voyez aucune mention de Linq-to-SQL (autre que l'étiquette), et oui, j'ai remarqué la "durée de 60 minutes" - c'est un peu plus compliqué bien que. Peut-être que cette approche fera - nous verrons - jusqu'à l'OP pour faire un appel :-) –

0

Si vous travaillez avec un ensemble 60 minutes bloc de temps (par exemple, les 60 dernières minutes à partir de maintenant) alors il est relativement facile:

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 

Si vous êtes pour tout vouloir Intervalle de 60 minutes, il devient plus complexe!

+0

de préférence à la recherche d'une fenêtre roulante de 60 minutes, mais peut avoir à régler avec des heures fixes. – scott

1

Je ne connais pas un moyen facile de calculer cette mesure, mais j'espère que cela vous aidera. Sans une sorte de curseur SQL, je générerais une table SQL d'intervalles possibles, avec des horodateurs de début et de fin (2009-09-02T00: 00 à 2009-09-02T00: 59, 2009-09-02T00: 01 à 2009-09 -02T01: 00, etc.), puis une jointure croisée en utilisant LINQ to 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(); 

Je n'ai pas essayé le code, mais il devrait vous aider à démarrer. Vous pouvez améliorer la performance en limitant le temps de vérification (7 jours, 30 jours, etc.) ou en générant moins d'intervalles (en commençant par le quart d'heure, peut-être).

1

Si vous voulez plutôt "quel produit a reçu le plus de commentaires dans un bloc de 60 minutes entre dateX et dateY" alors il devient un peu plus complexe. Une façon d'y penser est "pour chaque avis pendant cette période combien d'autres avis sont là pour le même ID de produit dans les 60 minutes suivantes". Une fois que vous avez cette logique, la requête devient plus claire:

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 

Hows that?

0

Si vous étiez satisfait des heures fixes pour vos fenêtres, je peux envisager de le faire un peu plus malin, en utilisant une gâchette. Le déclencheur insère/met à jour dans une table 'log', et fait simplement la différence entre l'insertion ou la mise à jour en fonction de l'heure actuelle.

Vous pourriez combiner avec cela l'une des autres approches, il faudrait ajouter une belle couche de mise en cache.

Questions connexes