2011-12-06 4 views
0

J'ai un tableau avec des messages et je veux générer un graphique qui montre combien de messages ont été faits au cours des 30 dernières minutes, et les 30 dernières minutes avant cela, etc Les messages sont sélectionnés par leur post_handler et post_status.Générer des statistiques dans MySQL

La structure de la table ressemble à ceci.

CREATE TABLE IF NOT EXISTS `posts` (
    `post_title` varchar(255) NOT NULL, 
    `post_content` text NOT NULL, 
    `post_date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `post_handler` varchar(255) NOT NULL, 
    `post_status` tinyint(4) NOT NULL, 
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`), 
    KEY `post_status` (`post_status`), 
    KEY `post_status_2` (`post_status`,`id`), 
    KEY `post_handler` (`post_handler`), 
    KEY `post_date_added` (`post_date_added`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2300131 ; 

Les résultats que j'aimerais recevoir, triés après post_date_added.

period_start period_end posts 
2011-12-06 19:23:44 2011-12-06 19:53:44 10 
2011-12-06 19:53:44 2011-12-06 20:23:44 39 
2011-12-06 20:23:44 2011-12-06 20:53:44 40 

droit Je vais maintenant utiliser la solution où je dois exécuter cette requête plusieurs fois, puis insérez les données dans une autre table à partir du script PHP.

SELECT COUNT(*) FROM posts WHERE post_handler = 'test' AND post_status = 1 AND post_date_added BETWEEN '2011-12-06 19:23:44' AND '2011-12-06 19:53:44' 

Connaissez-vous une autre solution? Est-il possible d'exécuter une requête qui insère également des résultats dans la base de données, tout en une requête?

Répondre

1

En (très) bref: oui, vous pouvez insérer les résultats d'une requête dans une autre table. Jetez un oeil à INSERT ... SELECT ici: http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

Essentiellement, vous voulez simplement changer ce que vous avez à quelque chose comme

INSERT INTO post_statistics_table (period_start, period_end, posts) 
    SELECT ?, ?, COUNT(*) FROM posts 
     WHERE post_handler = 'test' 
      AND post_status = 1 
      AND post_date_added BETWEEN ? AND ? 

puis remplir les quatre ? s avec les mêmes deux DATETIME s, répétée. ($from, $to, $from, $to)

1

Il est assez facile de regrouper par des paramètres de temps distinctifs, comme l'heure, minute, jour ou quoi que ce soit. Si vous voulez groupe cela en une heure, une requête possible pourrait ressembler à ceci:

SELECT DATE_FORMAT(post_date_added,"%Y-%m-%d %H") AS "_Date", 
    COUNT(*) 
FROM posts 
WHERE post_handler = 'test' 
    AND post_status = 1 
GROUP BY _Date; 

(cela avec un exécuter outil de requête mysql de votre choix pour voir la sortie). Toutefois, si vous voulez considérer 30 minutes comme la base de votre groupe, la partie SQL deviendra plus délicate. A cet effet spécial, puisque vous avez suffit de diviser en deux sous-ensembles différents, peut-être travailler avec cette approche:

SELECT DATE_FORMAT(post_date_added,"%Y-%m-%d %H") AS "_Date", 
    "00" AS "semihour", 
    COUNT(*) 
FROM posts 
WHERE post_handler = 'test' 
    AND DATE_FORMAT(post_date_added,"%i") < 30 
    AND post_status = 1 
GROUP BY _Date 
UNION 
SELECT DATE_FORMAT(post_date_added,"%Y-%m-%d %H") AS "_Date", 
    "30" AS "semihour", 
    COUNT(*) 
FROM posts 
WHERE post_handler = 'test' 
    AND DATE_FORMAT(post_date_added,"%i") >= 30 
    AND post_status = 1 
GROUP BY _Date; 

Encore une fois, exécutez un outil de requête mysql de votre choix pour voir la sortie. Vous pourriez ajouter des distinctions mathématiques là aussi en travaillant avec CASE ou IF et autres, mais personnellement, je serais soit groupe par heure ou par minute juste pour garder la partie SQL plus facile.

Pour ajouter directement ces numéros dans votre base de données graphique, utilisez cette syntaxe:

INSERT INTO yourtable (yourfields) 
SELECT ... 

Plus de détails sur ce qui peut être trouvé here dans la documentation MySQL.

Questions connexes