Mysql group by hour don't work with week range - mysql

I have time range in database:
date temp
2014-05-09 20:40:01 19.6875
2014-05-09 20:50:01 19.375
.....................
2014-05-10 00:10:01 17.5
........................
2014-05-23 08:25:01 27.4375
And i want get all AVG temperature with week group by hour. Here sql query:
SELECT AVG( `temp` ) , `date` FROM `temperature` WHERE `date` BETWEEN '2014-05-16 11:06' AND '2014-05-23 11:06' GROUP BY HOUR( `date` )
But in result i have only value with range from 2014-05-16 23:06:02 to 2014-05-17 00:05:01
And not have error.
Help me find my mistake.
Sory for my bad English

This is because when you use GROUP BY and display a field that isn't being grouped, mysql can't show you all the values of that field. So it just shows one.
This query makes more sense:
SELECT AVG( `temp` ) , HOUR(`date`) FROM `temperature` WHERE `date` BETWEEN '2014-05-16 11:06' AND '2014-05-23 11:06' GROUP BY HOUR( `date` )
Or this one (after discussion)
SELECT AVG( temp ) ,
YEAR(date),
MONTH(date),
DAY(date),
HOUR(date)
FROM temperature
WHERE date BETWEEN '2014-05-16 11:06' AND '2014-05-23 11:06'
GROUP BY YEAR(date),MONTH(date),DAY(date),HOUR(date)

Related

MySQL Full Group by

Since my web-host has updated the MySQL server version, my old SQL Query is not working anymore:
select COUNT(ID) AS Anzahl,
DAY(STR_TO_DATE(created_at, '%Y-%m-%d')) AS Datum
from `leads`
where `created_at` >= 2018-02-01
and `created_at` <= 2018-02-15
and `shopID` = 20
group by DAY(created_at)
order by DAY(created_at) asc
That means, I have to create a full group by query. I already have read this article but I don't really get it.
I should name all columns which are unique
Thats what I don't get. If I want to count the ID, I cannot create a group by ID query because in this case my count would always be 1. Could anybody please explain to me how full group by works and how my statement would like with a full group by statement?
Just use the same expression in the select as in the group by:
select COUNT(ID) AS Anzahl, DAY(created_at) AS Datum
from `leads` l
where `created_at` >= '2018-02-01' and
`created_at` <= '2018-02-15' and
`shopID` = 20
group by DAY(created_at)
order by DAY(created_at) asc;
You also need single quotes around the date constants.
Your select and group by columns doesn't match. You should make them same. Try below query:
select COUNT(ID) AS Anzahl,
DAY(STR_TO_DATE(created_at, '%Y-%m-%d')) AS Datum
from `leads`
where `created_at` >= 2018-02-01
and `created_at` <= 2018-02-15
and `shopID` = 20
group by Datum
order by Datum asc

How to group by time slot between two dates

I have a question that make me feel silly !
I have to do some stats on the use of my apps.
I have a table call : customer_point
id int(11) auto_increment
id_customer int(11)
type_point int(11)
date timestamp CURRENT_TIMESTAMP
I want to make this request for the entire month (with a row for each night ;) ) :
SELECT COUNT( id_customer ) , type_point, date(date)
FROM customer_point
WHERE date BETWEEN "2014-06-01 20:00:00" AND "2014-06-02 10:00:00"
GROUP BY type_point, date;
I nearly sure that i miss a crusial point but i can't find witch one.
Thank you very much for reading me !
Bye,
edit :
Sample :
INSERT INTO `customer_point` ( `id` , `id_customer` , `type_point`, `date` )
VALUES ( '', '15', '1', '2014-06-01 22:50:00'), ( '', '15', '1', '2014-06-01 23:52:00'), ( '', '15', '1', '2014-06-02 9:50:00'), ( '', '15', '1', '2014-06-30 22:50:00'), ( '', '15', '1', '2014-06-30 23:52:00'), ( '', '15', '1', '2014-07-01 02:50:00', ( '', '15', '1', '2014-07-01 09:50:00');
result :
1, 3, 2014-06-01
1, 4, 2014-06-30
I hope this will help everbody to understand my probleme :/
If you just want coutns of the actual data, check the date is within the range you are interested in and that the time is at night (ie, greater than 8pm or less than 10am, if would seem from your SQL):-
SELECT type_point, date(customer_point.date) AS aDate, COUNT( id_customer )
FROM customer_point
WHERE DATE(customer_point.date) BETWEEN "2014-06-01" AND "2014-06-30"
AND TIME(customer_point.date) >= '20:00:00' OR TIME(customer_point.date) <= '10:00:00'
GROUP BY type_point, aDate;
To get a row per day, irrespective of whether there is any data that day(ie, a count of zero it no data) then you need to generate a list of dates and then LEFT JOIN your data to it.
Something like this:-
SELECT sub0.aDate, type_point, COUNT( id_customer )
FROM
(
SELECT DATE_ADD('2014-06-01', INTERVAL units.i + tens.i * 10 DAY) AS aDate
FROM
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN
(SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) tens
) sub0
LEFT OUTER JOIN customer_point
ON sub0.aDate = date(customer_point.date)
WHERE sub0.aDate BETWEEN "2014-06-01" AND "2014-06-30"
GROUP BY sub0.aDate, type_point;
You would also probably need to generate a list of type_point values.
EDIT - to go with the updated question, can you just subtract 10 hours from the date / time. So 10am on the 1st July becomes midnight on the 30th June?
SELECT type_point, date(DATE_ADD(customer_point.date, INTERVAL -10 HOUR)) AS aDate, COUNT( id_customer )
FROM customer_point
WHERE DATE(DATE_ADD(customer_point.date, INTERVAL -10 HOUR)) BETWEEN "2014-06-01" AND "2014-06-30"
AND TIME(customer_point.date) >= '20:00:00' OR TIME(customer_point.date) <= '10:00:00'
GROUP BY type_point, aDate;
SQL fiddle:-
http://www.sqlfiddle.com/#!2/ddc95/2
The issue with this is whether items from before 10am on the 1st of June count as dates for May or for June?
Using mysql you even could do
WHERE date LIKE "2014-06-%"
Edit: You need exactly from 20:00 and then you have to take in account the first day of the next mounth until the 22:00...
Ok, then just substract those 20 hours to the date:
SELECT DATE_SUB(column, INTERVAL 20 HOUR)....
Finally:
SELECT COUNT( id_customer ) , type_point, DATE_SUB(date, INTERVAL 20 HOUR) as mydate
FROM customer_point
WHERE mydate LIKE "2014-06-%"
GROUP BY type_point, date;

mysql group by day with count multi types of records

i have a table with id | type | publishedon
type may be 1,2,3 or 4 (int) value
i want to select posts for every day
now i'm using
SELECT FROM_UNIXTIME( `publishedon` , "%Y-%m-%d" ) AS `day` , count( id ) AS listings,
TYPE FROM posts
WHERE (
FROM_UNIXTIME( publishedon ) >= SUBDATE( NOW( ) , 30 )
)
GROUP BY `day`
the result
day listings
2013-09-02 17
2013-09-05 105
i want make listings filed more detailed like
day type_1 type_2 type_3 type_4
2013-09-02 10 4 6 3
2013-09-05 6 4 1 3
You simply need to put all your type values:
SELECT
FROM_UNIXTIME( `publishedon` , "%Y-%m-%d" ) AS `day`,
count(id) AS listings,
(SELECT COUNT(id) FROM `posts` WHERE `type`=1 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_1`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=2 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_2`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=3 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_3`,
(SELECT COUNT(id) FROM `posts` WHERE `type`=4 AND FROM_UNIXTIME(`publishedon`, "%Y-%m-%d")=`day`) AS `type_4`
FROM
`posts`
WHERE
FROM_UNIXTIME(`publishedon`) >= SUBDATE(NOW(), 30)
GROUP BY
`day`
but in fact, that will work slow since there are functions in conditions. If it is only a formatting matter, it's better to act like:
SELECT
FROM_UNIXTIME(`publishedon`, "%Y-%m-%d" ) AS `day`,
`type`,
count( id ) AS listings,
FROM
`posts`
WHERE
-- this should be better evaluated in application
-- since will not produce index using too:
FROM_UNIXTIME(`publishedon`) >= SUBDATE(NOW(), 30)
GROUP BY
`day`,
`type`
and then create desired formatting inside application.

count of sum with group by [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculate a running total in MySQL
I need to get the sum of counts which is grouped for each of the dates.Now I am running the following query and getting the out put as follows :
SELECT `timestamp` , COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
and I am getting
OUTPUT:
timestamp count(*)
-------------------------------------------------- -----------
2013-01-04 07:58:21 4
2013-01-05 09:28:56 38
2013-01-06 00:03:04 10
Now what I need is, I need to get the total sum of the counts grouped by date. That is for the second date it should be 42 and for third date it should be 52. How can I do this in a query?
Give it a try:
SELECT `timestamp` , #sum:= ifnull(#sum, 0 ) + COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
Try :
SELECT
timestamp t ,
(select count(*) from A where timestamp <= t)
FROM A
GROUP BY timestamp
ORDER BY timestamp
Can you try below SQL
SELECT DATE_FORMAT( ts_date , '%Y-%m-%d' ) as ts_dt_out, SUM(cnt)
FROM
(
SELECT `timestamp` ts_date , COUNT( * ) as cnt
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE_FORMAT( `timestamp` , '%Y-%m-%d' )
)
as inner
WHERE ts_date >= '2013-01-04 07:12:12'
GROUP BY ts_dt_out
Note: Not tested let me know if it does not work
Here is a simple way
SELECT
`timestamp` ,
COUNT( * )
FROM `A`
WHERE `timestamp` >= '2013-01-04 07:12:12'
GROUP BY DATE(`timestamp`)

get avg data every 15 min

I'm new to tsql and use mysql db. Seen an example code(at below) to get data from database every 2 hour:
SELECT date(`dateTime`) dateDay, 2*floor(date_format(`dateTime`,'%H')/2) dateHour,
avg(channel1), avg(channel2), avg(channel3)
FROM `Table`
WHERE `id` =1
AND `dateTime` >= '2011-10-15 00:00:01'
AND `dateTime` <= '2011-10-17 23:59:59'
Then I did few changes based on the above code to get data every 15 minutes:
SELECT date(`dateTime`) dateDay, 15*floor(date_format(`dateTime`,'%i')/15) dateHour,
avg(channel1), avg(channel2), avg(channel3)
FROM `Table`
WHERE `id` =1
AND `dateTime` >= '2011-10-15 00:00:01'
AND `dateTime` <= '2011-10-17 23:59:59'
group by date(`dateTime`), 15*floor(date_format(`dateTime`,'%i')/15)
However the query is not correct.
My questions are:
How to amend the query to get data every 15 min?
How to write sql query to get all data as well? and dateDay and dateHour columns need to be here.
1: every 15 minutes:
SELECT date(dateTime) dateDay, 2*floor(date_format(dateTime,'%H')/2) dateHour,
avg(channel1), avg(channel2), avg(channel3)
-->
SELECT date(`dateTime`) dateDay
,CONCAT( 2*floor(date_format(`dateTime`,'%H')/2), ':', 15*FLOOR(DATE_FORMAT(`dateTime`, '%i')/15)) dateQuarter
,avg(channel1), avg(channel2), avg(channel3)
FROM `Table`
WHERE `id` =1
AND `dateTime` >= '2011-10-15 00:00:01'
AND `dateTime` <= '2011-10-17 23:59:59'
GROUP BY 1,2;
2: all data. I wasn't really sure what you wanted. but here's every row with hour:minute in dateHour field.
SELECT date(`dateTime`) dateDay,
,DATE_FORMAT(`dateTime`, '%H:%i') dateHour,
FROM `Table`
WHERE `id` =1
AND `dateTime` >= '2011-10-15 00:00:01'
AND `dateTime` <= '2011-10-17 23:59:59'