J'ai quelques difficultés avec les commandes MySQL que je veux faire.
SELECT a.timestamp, name, count(b.name)
FROM time a, id b
WHERE a.user = b.user
AND a.id = b.id
AND b.name = 'John'
AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00'
GROUP BY a.timestamp
Ceci est ma déclaration de sortie actuelle.
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:32:22 John 2
2010-11-16 10:35:12 John 7
2010-11-16 10:36:34 John 1
2010-11-16 10:37:45 John 2
2010-11-16 10:48:26 John 8
2010-11-16 10:55:00 John 9
2010-11-16 10:58:08 John 2
Comment les regrouper en résultats d'intervalle de 5 minutes?
Je veux que ma sortie soit comme
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:30:00 John 2
2010-11-16 10:35:00 John 10
2010-11-16 10:40:00 John 0
2010-11-16 10:45:00 John 8
2010-11-16 10:50:00 John 0
2010-11-16 10:55:00 John 11
Cela fonctionne à chaque intervalle.
PostgreSQL
SELECT
TIMESTAMP WITH TIME ZONE 'Epoch' +
INTERVAL '1 second' * round(extract('Epoch' from timestamp) / 300) * 300,
as timestamp,
name,
count(b.name)
FROM time a, id
WHERE …
GROUP BY
round(extract('Epoch' from timestamp) / 300), name
MySQL
SELECT
timestamp, -- not sure about that
name,
count(b.name)
FROM time a, id
WHERE …
GROUP BY
UNIX_TIMESTAMP(timestamp) DIV 300, name
Vous devriez plutôt utiliser GROUP BY UNIX_TIMESTAMP(time_stamp) DIV 300
au lieu de round (../ 300) en raison des arrondis. J'ai constaté que certains enregistrements sont comptés dans deux ensembles de résultats groupés.
Pour postgres, j’ai trouvé plus facile et plus précis d’utiliser le
fonction, comme:
select name, sum(count), date_trunc('minute',timestamp) as timestamp
FROM table
WHERE xxx
GROUP BY name,date_trunc('minute',timestamp)
ORDER BY timestamp
Vous pouvez fournir diverses résolutions comme «minute», «heure», «jour», etc. à date_trunc.
je suis tombé sur le même problème.
J'ai trouvé qu'il est facile de grouper par n'importe quel intervalle de minute est divisez simplement Epoch par quelques minutes, puis arrondissez ou utilisez le sol pour éviter le reste. Donc, si vous voulez obtenir un intervalle dans 5 minutes, vous utiliserez 300 secondes .
SELECT COUNT(*) cnt, to_timestamp(floor((extract('Epoch' from timestamp_column) / 300 )) * 300) AT TIME ZONE 'UTC' as interval_alias FROM TABLE_NAME GROUP BY interval_alias
</ pre></ code>
interval_alias cnt ------------------- ---- 2010-11-16 10:30:00 2 2010- 11-16 10:35:00 10 2010-11-16 10:45:00 8 2010-11-16 10:55:00 11Cela retournera les données correctement groupe par intervalle de minutes sélectionné; Cependant, il ne renverra pas les intervalles qui ne contiennent aucune donnée. Pour obtenir ces intervalles vides, nous pouvons utiliser la fonction generate_series .
SELECT generate_series(MIN(date_trunc('hour',timestamp_column)), max(date_trunc('minute',timestamp_column)),'5m') as interval_alias FROM TABLE_NAME
</ pre></ code> Résultat:
interval_alias ------------------- 2010-11-16 10:30:00 2010-11-16 10:35 : 00 2010-11-16 10:40:00 2010-11-16 10:45:00 2010-11-16 10:50:00 2010-11-16 10 : 55: 00Maintenant, pour obtenir le résultat avec un intervalle sans occurrences, il suffit de outer joindre les deux jeux de résultats.
SELECT series.minute as interval, coalesce(cnt.amnt,0) as count from ( SELECT count(*) amnt, to_timestamp(floor((extract('Epoch' from timestamp_column) / 300 )) * 300) AT TIME ZONE 'UTC' as interval_alias from TABLE_NAME group by interval_alias ) cnt RIGHT JOIN ( SELECT generate_series(min(date_trunc('hour',timestamp_column)), max(date_trunc('minute',timestamp_column)),'5m') as minute from TABLE_NAME ) series
</ pre>sur series.minute = cnt.interval_alias
</ code> Le résultat final comprendra la série avec tous les intervalles de 5 minutes, même ceux sans valeur.
compte d'intervalles ------------------- ---- 2010-11-16 10:30:00 2 2010- 11-16 10:35:00 10 2010-11-16 10:40:00 0 2010-11-16 10:45:00 8 2010-11-16 10:50:00 0 2010-11-16 10:55:00 11L'intervalle peut être facilement modifié en ajustant le dernier paramètre de generate_series. Dans notre cas, nous utilisons '5m' mais cela pourrait être tout intervalle souhaité.
La requête sera quelque chose comme:
SELECT
DATE_FORMAT(
MIN(timestamp),
'%d/%m/%Y %H:%i:00'
) AS tmstamp,
name,
COUNT(id) AS cnt
FROM
table
GROUP BY ROUND(UNIX_TIMESTAMP(timestamp) / 300), name
Vous devrez probablement diviser votre horodatage en ymd: HM et utiliser DIV 5 pour fractionner les minutes en bacs de 5 minutes - quelque chose comme:
select year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 5,
name,
count(b.name)
FROM time a, id b
WHERE a.user = b.user AND a.id = b.id AND b.name = 'John'
AND a.timestamp BETWEEN '2010-11-16 10:30:00' AND '2010-11-16 11:00:00'
GROUP BY year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 12
... et ensuite, la sortie dans le code client apparaîtra comme vous le souhaitez. Ou bien, vous pouvez construire la chaîne de date entière en utilisant l'opérateur sql concat au lieu d'obtenir des colonnes séparées, si vous le souhaitez.
select concat(year(a.timestamp), "-", month(a.timestamp), "-" ,day(a.timestamp),
" " , lpad(hour(a.timestamp),2,'0'), ":",
lpad((minute(a.timestamp) DIV 5) * 5, 2, '0'))
... et puis groupe sur ça
Celui-ci, ça va:
select
from_unixtime(unix_timestamp(timestamp) - unix_timestamp(timestamp) mod 300) as ts,
sum(value)
from group_interval
group by ts
order by ts
;
Je ne sais pas si vous en avez encore besoin.
SELECT FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP(timestamp))/300)*300) AS t,timestamp,count(1) as c from users GROUP BY t ORDER BY t;
2016-10-29 19:35:00 | 2016-10-29 19:35:50 | 4 |
2016-10-29 19:40:00 | 2016-10-29 19:40:37 | 5 |
2016-10-29 19:45:00 | 2016-10-29 19:45:09 | 6 |
2016-10-29 19:50:00 | 2016-10-29 19:51:14 | 4 |
2016-10-29 19:55:00 | 2016-10-29 19:56:17 | 1 |
J'ai découvert qu'avec MySQL, la requête correcte est probablement la suivante:
SELECT SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 ) AS ts_CEILING,
SUM(value)
FROM group_interval
GROUP BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 )
ORDER BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
'%Y-%m-%d %H:%i:%S' ) , 1, 19 ) DESC
Laissez-moi savoir ce que vous pensez.
select
CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2)) AS '5MINDATE'
,count(something)
from TABLE
group by CONCAT(CAST(CREATEDATE AS DATE),' ',datepart(hour,createdate),':',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2))