2008-12-01 6 views
2
SELECT 
    avg(con_hits) as avg_hits 
FROM 
    content 
WHERE 
    con_type = 1 
    AND con_posttime < $twelve_hrs_ago 
    AND con_refresh = 0 
ORDER BY 
    con_posttime DESC 
LIMIT 100 

Je voudrais qu'il aille au premier enregistrement qui a été posté il y a au moins 12 heures (désigné par la variable $twelve_hrs_ago qui a l'horodatage approprié), et prendre la moyenne de la colonne con_hits, pour les 100 dossiers . Dans mon exemple, il ne tient pas compte du LIMIT et prend la moyenne de chaque enregistrement de la table.Comment réparer cette requête MySQL?

Existe-t-il un moyen de contourner cela?

Répondre

12

LIMIT est appliqué au résultat, après AVG est calculé. Vous pouvez faire ce que vous voulez, avec une sous-sélection:

SELECT avg(con_hits) as avg_hits 
FROM (
    SELECT con_hits 
    FROM content 
    WHERE 
    con_type = 1 
    AND con_posttime < $twelve_hrs_ago 
    AND con_refresh = 0 
    ORDER BY con_posttime DESC 
    LIMIT 100 
) x; 

Vous pouvez utiliser la base de données pour calculer le décalage de temps aussi. Remplacer $twelve_hrs_ago ci-dessus:

date_add(now(), interval -12 hour) 
+0

Parfait! Dans votre deuxième suggestion, l'utilisation du code que vous avez fourni aboutit à avg_hits étant NULL. Et quel est le point de ce x à la fin? –

+0

À mon avis. Il serait plus lisible d'utiliser date_sub à la place. Le nom de la fonction indique le but. –

+0

La valeur x à la fin est requise car vous devez attribuer un nom de corrélation (c'est-à-dire un alias de table) à toute requête dérivée dans la clause FROM. –

1

Qu'en est-:


SELECT avg(con_hits) as avg_hits FROM (
    SELECT con_hits FROM content 
    WHERE con_type = 1 AND con_posttime < $twelve_hrs_ago AND con_refresh = 0 
    ORDER BY con_posttime DESC 
    LIMIT 100 
    ) 

Mysql prend en charge les sous-requêtes, donc cela peut le faire pour vous.

http://dev.mysql.com/doc/refman/5.0/en/subqueries.html

Questions connexes