MySQL Multiple Group by with Dates - mysql

I have the following Database with example content:
Now I want for a certain siteid for every weekday (Monday, ..., Sunday) for every tsegment-TIME (date independend) on this day the average category.
I have to parse the date from tstamp or tsegment. That basically work.
Then I have to parse the time - that does not work. Don't know why.
I surmise it is because of the group by Weekday. But I do not know how to solve it.
That is my query:
SELECT
siteid,
DAYNAME(STR_TO_DATE(tstamp, "%Y-%m-%d")) as Day,
STR_TO_DATE(tsegment,'%h:%i:%s') as Segment,
AVG(category)
FROM `ITODDB_Occupancy`
WHERE siteid = 350
GROUP BY
Segment, Day
The result is
I want output like this:
siteid Day Segment AVG(Category)
350 Monday 11:10:00 3.987
350 Monday 11:15:00 2.123
350 Tuesday 08:00:00 3.999
350 Tuesday 09:35:00 2.500
... ... ... ...
350 Sunday 03:45:00 1.432
350 Sunday 03:55:00 1.555

From what I've seen and worked with, the TIMESTAMP type can be somewhat wonky with STR_TO_DATE. Instead, use a combination of FROM_UNIXTIME/DATE_FORMAT
DATE_FORMAT(FROM_UNIXTIME('2016-01-20T11:30:20'), '%h:%i:%s')
That should give you what you need.
Example:
SELECT
siteid,
DAYNAME(STR_TO_DATE(tstamp, "%Y-%m-%d")) as Day,
DATE_FORMAT(FROM_UNIXTIME(tsegment), '%h:%i:%s') as Segment,
AVG(category)
FROM `ITODDB_Occupancy`
WHERE siteid = 350
GROUP BY
Segment, Day

Related

Add weekend values to Monday SQL

I am working in mySQL and I currently have a count of total orders by day, but I would like to add Saturday and Sunday orders to Monday then remove Saturday and Sunday values. I have done some research on this but I cannot seem to find anything similar to what I am trying to do.
My current data table looks like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-8-2020 24
8-9-2020 33
8-10-2020 18
8-11-2020 10
8-12-2020 25
8-13-2020 15
I need it to look something like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-10-2020 75
8-11-2020 10
8-12-2020 25
8-13-2020 15
In this one the Daily counts for the 8th and 9th are added to the 10th, then removed, because they are weekend days. Thank you in advance for your help!
Consider using a case expression to adjust the date:
select
case weekday(date)
when 5 then date + interval 2 day
when 6 then date + interval 1 day
else date
end as new_date,
sum(daily_count) as daily_count
from mytable
group by new_date

MySQL average value of each hour for the last 30 days

I have a table, that is updated every minute and I need to calculate the average value of each hour, for the values of the last 30 days.
Timestamp | SB1_AC_GES_DIFF
2020-07-14 15:13:04 30
2020-07-14 15:12:07 27
... ...
I want to save the results in a second table named avgTable like this
Timestamp | AVG_SB1
15:00 29
16:00 32
... ...
It would be perfect if the table could update itself once a day, maybe when it's 12 o'clock and the the date part for the day changes.
You can try:
INSERT INTO avg_table
SELECT Date_format(Timestamp, "%h:00:00") AS HourlyTimeStamp,
Avg(sb1_ac_ges_diff) AS "AVG_SB1"
FROM table
WHERE Timestamp between DATEADD(DAY, -30, GETDATE()) AND GETDATE()
GROUP BY 1
Assuming that you want the average rolling average, agnostic of the day.
You can just use the hour() function:
select hour(timestamp) as hh, avg(sb1_ac_ges_diff)
from t
group by hh;
You can convert this to a string or time if you want, but that does not seem useful to me.
If you actually want the hour for each day, then:
select date(timestamp) as dd, hour(timestamp) as hh, avg(sb1_ac_ges_diff)
from t
group by dd, hh;

Get average day or week values

I have statistical data like this:
time val1
1424166578 51
1424166877 55
1424167178 57
1424167477 57
time is a unix timestamp. There is one record every 5 minutes excluding nights and sundays. This continues over several weeks.
Now I want to get these values for an average day and an average week. The result should include values for every 5 minutes like normal but for average past days or weeks.
The result should look like this:
time val1
0 43.423
300 46.635
600 51.887
...
So time could be a timestamp with relative time since day or week start. Perhaps it is better to use DATETIME... not sure.
If I use GROUP BY FROM_UNIXTIME(time, '%Y%m%d') for example I get one value for the whole day. But I want all average values for all days.
You seem to be interested in grouping dates by five minute intervals instead of dates. This is fairly straightforward:
SELECT
HOUR(FROM_UNIXTIME(time)) AS HH,
(MINUTE(FROM_UNIXTIME(time)) DIV 5) * 5 AS MM,
AVG(val1) AS VAL
FROM your_table
WHERE time > UNIX_TIMESTAMP(CURRENT_TIMESTAMP - INTERVAL 7 DAY)
GROUP BY HH, MM
The following result will explain how date is clamped:
time FROM_UNIXTIME(time) HH MM
1424166578 2015-02-17 14:49:38 14 45
1424166877 2015-02-17 14:54:37 14 50
1424167178 2015-02-17 14:59:38 14 55
1424167477 2015-02-17 15:04:37 15 00
I would approach this as:
select date(from_unixtime(time)) as day, avg(val)
from table t
group by date(from_unixtime(time))
order by day;
Although you can use the format argument, I think of that more for converting the value to a string than to a date/time.

Mysql query for group by month

I am looking to do something like get all rows from table
where date >='2012-05-05' and date<='2012-07-20'
I want MySQL to return "group by" rows mont wise incremented from
2012-05-05 to 2012-06-05(incerement 1 month)
2012-06-06 to 2012-07-06(increment 1` month)
and remaining 2012-07-07 to 2012-07-20 (group the remaining 14 days)
how can i write my query to achieve the same?
Thank you...
Try this solution:
You can GROUP BY the number of months elapsed from your parameter minimum (2012-05-05) + 1 to the date in each row via the TIMESTAMPDIFF() function:
GROUP BY TIMESTAMPDIFF(MONTH, '2012-05-05' + INTERVAL 1 DAY, date)
The reason why we +1 day to your minimum parameter is because:
2012-05-05 to 2012-06-04 is 0 months, but...
2012-05-05 to 2012-06-05 is 1 month
^ Because of that, the row(s) on 2012-06-05 would be grouped separately from dates that had 0 months elapsed when we actually want it grouped WITH them.
Edit: I was fiddling around with this solution not only grouping by the month intervals, but also displaying the from and to dates of each interval.
Check it out:
SQLFiddle Demo
You could use the case expression and then group by on the result of case.
SELECT
CASE
WHEN where date >='2012-05-05' and date<='2012-06-05' THEN 1
WHEN where date >='2012-06-06' and date<='2012-07-06' THEN 2
ELSE 3
END AS period, COUNT(*)
FROM your_table
GROUP BY period
Hope this help, I assumed the date range is dynamic like this :
2012-01-01 to 2012-02-01
2012-02-02 to 2012-03-02
2012-03-03 to 2012-04-03
2012-04-04 to 2012-05-04
2012-05-05 to 2012-06-05
...
So, I can group it using :
SELECT *, IF(day(date)>=month(date), month(date), month(date)-1) as PERIOD
FROM your_tablename
GROUP BY PERIOD;

Why does ORDER BY DAYOFWEEK()'s return not begin with Sunday?

I have the following (MySQL) table called "tweets":
tweet_id created_at
---------------------
1 1298027046
2 1298027100
5 1298477008
I want MySQL returning the number of tweets per day of the week; taking the above data it should return:
Sunday 1
Monday 2
I now have the following query to accomplish this:
SELECT COUNT(tweet_id) AS tweets, DAYNAME(FROM_UNIXTIME(`created_at`)) AS day
FROM tweets
GROUP BY day
ORDER BY DAYOFWEEK(day)
This however returns a list that starts with Wednesday:
Wednesday 2019
Tuesday 2072
Monday 932
Sunday 1433
Saturday 4321
Friday 643
Thursday 1542
How is this list ordered? Why not just Sun to Sat and how * can * I accomplish that?
DAYOFWEEK takes a date ('2011-02-26'), but you're giving it a day name ('Saturday').
Try to change the order clause like this
order by dayofweek(FROM_UNIXTIME(`created_at`))