2011-01-21 3 views
0

J'ai une table avec ID, valeur1, valeur2, valeur3 et tstamp (format TIMESTAMP) et j'essaie de grouper par jour et de trouver un total pour chaque jour, mais toutes les valeurs sont cumulables, ce qui pose un problème, parce que la somme (valeur1) ne marche pas donner la bonne sortie, voici mon code:PHP Mysql groupe par date à partir de valeurs cumulatives

$sql = "select date(tstamp), sum(".$column.") from mash group by date(tstamp) order by tstamp asc limit 10"; 
$result = mysql_query($sql); 
$previous = 0; 
$firstRun = true; 
while($row = mysql_fetch_array($result)) 
{ 
    $difference = $row[1] - $previous; 
    if (!$firstRun) 
    { 
    $strXML .= "<set name='".$row[0]."' value='".$difference."' color='AFD8F8' />"; 
    } 
    $previous = $row[1]; 
    $firstRun = false; 
} 

quelqu'un peut-il repérer la question dans ce code, ses pas la moindre erreur, son juste donner des réponses erronées.

EDIT:

Pour dissiper toute confusion, c'est le SQL:

-------------------------------------------------------- 

-- 
-- Table structure for table `mash` 
-- 

CREATE TABLE IF NOT EXISTS `mash` (
    `id` int(25) NOT NULL AUTO_INCREMENT, 
    `steam` int(25) NOT NULL, 
    `bore_water` int(25) NOT NULL, 
    `boiler1oil` int(25) NOT NULL, 
    `boiler2oil` int(25) NOT NULL, 
    `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5362 ; 

-- 
-- Dumping data for table `mash` 
-- 

INSERT INTO `mash` (`id`, `steam`, `bore_water`, `boiler1oil`, `boiler2oil`, `tstamp`) VALUES 
(2, 436, 73, 15, 1, '2010-11-25 12:28:03'), 
(3, 495, 74, 36, 1, '2010-11-25 12:38:04'), 
(4, 553, 76, 58, 1, '2010-11-25 12:48:09'), 
(5, 565, 77, 74, 1, '2010-11-25 12:58:05'), 
(6, 584, 79, 78, 1, '2010-11-25 13:08:05'), 
(7, 630, 82, 100, 1, '2010-11-25 13:18:11'), 
(8, 686, 86, 130, 1, '2010-11-25 13:28:07'), 
(9, 740, 89, 151, 1, '2010-11-25 13:38:07'), 
(10, 780, 93, 173, 1, '2010-11-25 13:48:13'), 
(11, 883, 100, 218, 1, '2010-11-25 14:08:10'); 
+0

Ne pourriez-vous pas grouper par 'DATE (tstamp)' alors commander par la dernière entrée qui aurait la valeur que vous recherchez? –

+0

Je ne sais pas pourquoi il ne travaille pas Brad, mais sur certains points, il donne des résultats moins, ce qui n'est certainement pas juste. J'ai essayé desc et asc, ni le travail – benhowdle89

+0

@ benhowdle89: Je suis en train de remplir une base de données de démonstration sur ma fin maintenant, donc j'ai quelque chose à tester contre. Est-il prudent de supposer que vous cherchez à atteindre "valeur1", "valeur2", etc. à partir de la dernière entrée (dernière insérée) sur une base quotidienne (puisque la dernière est toujours la précédente plus nouvelle valeur?) –

Répondre

1

En supposant que je lis votre table correctement, vous cherchez la dernière entrée de « valeur1 » (ou valeur2, etc.) qui en effet est la somme (à en juger par votre mention des valeurs accumulative)

+----+------+---------------------+ 
| id | val | tstamp    | 
+----+------+---------------------+ 
| 6 | 1 | 2010-01-02 01:00:00 | 
| 7 | 4 | 2010-01-02 02:00:00 | 
| 8 | 6 | 2010-01-02 03:00:00 | 
| 9 | 15 | 2010-01-02 04:00:00 | 
| 10 | 20 | 2010-01-02 05:00:00 | <-- this value 
| 11 | 1 | 2010-01-03 01:00:00 | 
| 12 | 4 | 2010-01-03 02:00:00 | 
| 13 | 6 | 2010-01-03 03:00:00 | 
| 14 | 15 | 2010-01-03 04:00:00 | 
| 15 | 20 | 2010-01-03 05:00:00 | <- this value 
| 1 | 2 | 2010-02-01 01:00:00 | 
| 2 | 8 | 2010-02-01 02:00:00 | 
| 3 | 16 | 2010-02-01 03:00:00 | 
| 4 | 32 | 2010-02-01 04:00:00 | 
| 5 | 64 | 2010-02-01 05:00:00 | <- this value 
+----+------+---------------------+ 

Ensuite, vous devriez pouvoir utiliser MAX & DATE:

SELECT DATE(tstamp), MAX(val) 
FROM  mash 
GROUP  DATE(tstamp) 
ORDER BY tstamp ASC; 

qui produira:

+--------------+----------+ 
| DATE(tstamp) | MAX(val) | 
+--------------+----------+ 
| 2010-01-02 |  20 | 
| 2010-01-03 |  20 | 
| 2010-02-01 |  64 | 
+--------------+----------+ 
+0

Accepté Brad, merci! – benhowdle89

+0

Bonjour Brad, je suis conscient que vous m'avez donné une réponse complète, mais j'ai eu une pensée. Parce que chaque valeur est toujours plus grande que la valeur précédente (elle ne se réinitialise jamais non plus). Le problème que j'ai vu surgir est que dire pour le jour 1 la valeur maximum était 3456 (d'où le total pour ce jour) bien le jour 2 commencera avec 3456 et augmentera seulement. Par conséquent mon graphique que j'ai tracée continue d'augmenter parce que chaque total est également ajouté de la journée précédente! Cela a-t-il du sens? De toute façon autour de cela? – benhowdle89

+0

Peu importe - réparé! – benhowdle89

0

Si vous regroupez la date, il va groupe par le plus petit incrément de la date. Vous devriez être en train de regrouper le jour de la date. Quelque chose comme:

select DATE_FORMAT(tstamp, '%Y-%m-%c') as ymd, sum(".$column.") from mash group by ymd order by tstamp asc limit 10 

Ce qui vous donnera un format année-mois-date sur lequel il va regrouper. Si vous avez besoin d'accéder au mois l'année valeurs du jour et faire individuellement:

select YEAR(tstamp) as year, MONTH(tstamp) as month, DAY(tstamp) as day, sum(".$column.") from mash group by year, month, day order by tstamp asc limit 10 
+0

fyi, la fonction [DATE()] (http://dev.mysql.com/doc/refman/5.0/fr/date-and-time-functions.html#function_date) a le même résultat que votre DATE_FORMAT. –

+0

Hmm, merci Photon, comment cela s'intégrerait-il avec mon code ci-dessus? – benhowdle89

+0

Essentiellement pour remplacer la requête SQL elle-même. Et désolé j'ai raté la partie cumulative de votre description, et je vois que vous avez une réponse de travail. :) – photon

0

La partie clé de votre question n'est pas la partie GROUP BY, qui fonctionne très bien, il est ce que vous entendez par cumulables. Si vous voulez dire qu'une certaine colonne suit la quantité totale de pluie dans une année pour chaque jour (c.-à-d., Le nombre continue de monter parce que le delta entre deux enregistrements est la pluie réelle qui s'est produite ce jour-là) besoin de faire est d'abord se débarrasser du delta. Le SQL va être un peu poilu peu importe comment vous le faites, donc vous feriez probablement mieux de le faire en PHP, mais voici que j'essaie avec SQL.

create temporary table foo select * from bar; 

create temporary table non_accumulative 
select b.id, b.rain - f.rain as "rain", rain_timestamp from bar b join foo f on (f.id + 1) = b.id; 

select sum(rain), date(rain_timestamp) from non_accumulative group by date(rain_timestamp) order by rain_timestamp; 

Bien sûr, vous pouvez faire la même chose avec les sous-sélections, mais je trouve que les tables temporaires sont plus rapides.