I need Time Wise Sales Report in mysql,I get the Report like
Time Amount
19:00:00 2
20:00:00 5
21:00:00 0
22:00:00 0
23:00:00 14
but I need sum of Amount like
Time Amount
19:00:00 2
20:00:00 5
21:00:00 5
22:00:00 5
23:00:00 14
This is my Query
SELECT concat(MID(date_of_call, 12, 2),':00:00') TimeIntervel,COUNT(*) TotalEntries,date_format(date_of_call,'%d/%m/%Y') FROM ICC_MM_setup_suply
WHERE DATE_FORMAT(date_of_call,'%d/%m/%Y')='31/01/2017'
GROUP BY concat(MID(date_of_call, 12, 2),':00:00')
You can use User variables:
set #lastval := 0;
select
time,
#lastval := if(Amount = 0, #lastval, Amount) Amount
from t
order by time;
Related
Data sample:
dtime
id
2021-01-01 06:00:00
1
2021-01-01 06:00:00
2
2021-01-01 06:00:00
3
...
...
2021-01-01 12:00:00
1
2021-01-01 12:00:00
2
2021-01-01 12:00:00
3
...
...
...
...
2021-01-12 20:00:00
1
2021-01-12 20:00:00
2
2021-01-12 20:00:00
3
In the real dataset, ids are between 1 and 9999, dtime are every 5 minutes, 24h/day, and I'd like to sample only at certain times (eg 06, 12, 16, 20h).
The expected output is the average of count(id) values, grouped by DATE(dtime), but:
Only certain TIME(dtime) should be sampled (eg 06, 12, 16, 20h);
count(id) should ignore id that are not between 10 and 500;
count(id) should be discarded (and not considered for the average) if <3.
Output sample:
DATE(dtime)
AVG(count(id))
2021-01-01
31
2021-01-02
29
So far I've got:
SELECT dtime,count(id)
FROM cron5min
WHERE (TIME(dtime) = '06:00:00' OR TIME(dtime) = '12:00:00' OR TIME(dtime) = '16:00:00' OR TIME(dtime) = '20:00:00') AND id BETWEEN 10 AND 500 AND estado = 1
GROUP BY dtime
and then I'm using PHP to do the average and discard data according to 3.
I'm now trying to do this with a MySQL statement only, no PHP.
You need 2 levels of aggregation:
SELECT DATE(dtime) date, AVG(counter) avg_count
FROM (
SELECT dtime, COUNT(id) counter
FROM cron5min
WHERE TIME(dtime) IN ('06:00:00', '12:00:00', '16:00:00', '20:00:00')
AND id BETWEEN 10 AND 500
AND estado = 1
GROUP BY dtime
HAVING counter >= 3
) t
GROUP BY date
MySQL version 8.0
I want to calculate time difference between two datetime column.
And get rows where duration >= 12:00:00.
which I would normally do:
select id
, start_time
, end_time
, timediff(end_time, start_time) as duration
from table;
which I would get something like this:
id start_time end_time duration
0 1 2020-06-01 01:00:00 2020-06-01 14:00:00 13:00:00
1 2 2020-06-01 01:00:00 2020-06-01 18:00:00 17:00:00
2 3 2020-06-01 19:00:00 2020-06-02 10:00:00 15:00:00
3 4 2020-06-02 04:00:00 2020-06-02 16:00:00 12:00:00
For duration column I don't want times between 00:00:00 ~ 04:00:00 to be added towards the duration. So for the first row duration = 10:00:00 since 01:00:00~14:00:00 = 10:00:00, ignoring times between 00:00:00 ~ 04:00:00
same for second row we substract 3 hours from duration.
so my desired output would be:
id start_time end_time duration
0 1 2020-06-01 01:00:00 2020-06-01 14:00:00 10:00:00
1 2 2020-06-01 01:00:00 2020-06-01 18:00:00 14:00:00
2 3 2020-06-01 19:00:00 2020-06-02 10:00:00 11:00:00
3 4 2020-06-02 04:00:00 2020-06-02 16:00:00 12:00:00
There are lots of rows where times include minutes and seconds too.
Thanks in advance!
I've grabbed all rows where duration >= 12:00:00.
Then separated data into 4 regions depending on their start_time.
a_region = 00~04
b_region = 04~12
c_region = 12~16
d_region = 16~24
For a_region I've subtracted 04:00:00 - start_time which is time we should compensate to duration in a_region.
compensation = 04:00:00 - start_time
compensated_time = duration - compensation.
For b_region it needs no compensation if it has passed 00~04 it means it already passed duration = 12:00:00.
For c_region,
compensation = 16:00:00 - start_time
compensated_time = duration - compensation
For d_region since we've grabbed duration >= 12:00:00
it will pass all of 00~04 therefore
compensated_time = duration - 04:00:00.
I solved it using Python but above is the logic I've used.
One option uses greatest():
select id
, start_time
, end_time
, timediff(
greatest(,
end_time,
date_format(end_time, '%Y-%m-%d 04:00:00')
),
greatest(
start_time,
date_format(start_time, '%Y-%m-%d 04:00:00')
)
) as duration
from table;
MariaDB version 10.4.10.
I have a stock scraper script that fetches stock data every hour and inserts it into a MySQL database. The database structure is similar to this:
stocks( time_fetched DATETIME, fetch_id INT, name VARCHAR, price INT )
And some example data:
**time_fetched fetch_id name price**
2020-03-10 09:00:00 1 stock1 10
2020-03-10 09:00:00 1 stock2 15
2020-03-10 10:00:00 2 stock1 12
2020-03-10 10:00:00 2 stock2 20
2020-03-10 11:00:00 3 stock1 8
2020-03-10 11:00:00 3 stock2 18
I want a way to get price change for each stock between, say, stocks fetched at 09:00 and 10:00, or between 09:00 and 11:00. Something like this (pseudo code):
SELECT *, DIFF( current_price, price_one_hour_ago) AS change_1h, DIFF( current_price, price_two_hours_ago) AS change_2h
Is it possible to do this directly in MySQL? I am using a PHP script to display the data, so I might have to resort to do it in PHP instead.
You can use a CTE to generate prices delayed by 1 or 2 hours, and then compute the changes using those values (potentially using COALESCE to make NULL values into 0):
WITH prices AS (
SELECT time_fetched, name, price,
LAG(price, 1) OVER(PARTITION BY name ORDER BY time_fetched) AS price_1h,
LAG(price, 2) OVER(PARTITION BY name ORDER BY time_fetched) AS price_2h
FROM stocks
)
SELECT time_fetched, name, price,
COALESCE(price - price_1h, 0) AS change_1h,
COALESCE(price - price_2h, 0) AS change_2h
FROM prices
Output:
time_fetched name price change_1h change_2h
2020-03-10 09:00:00 stock1 10 0 0
2020-03-10 10:00:00 stock1 12 2 0
2020-03-10 11:00:00 stock1 8 -4 -2
2020-03-10 09:00:00 stock2 15 0 0
2020-03-10 10:00:00 stock2 20 5 0
2020-03-10 11:00:00 stock2 18 -2 3
Demo on dbfiddle also showing query results without COALESCE.
Suppose I have 5 records for a sales table.
ID Name datetime_col
1 ABC 2016-09-15 02:07:56
2 HSJ 2016-09-31 11:45:45
3 JSD 2016-11-26 07:09:56
4 JUH 2016-12-31 12:00:00
5 IGY 2017-01-13 14:00:07
I want to find how many records are there in sales table for each hour between 2016-09-15 AND 2017-01-13
Then result should be like
Hour sales_at_this_hour
2016-09-15 01:00:00 0
2016-09-15 02:00:00 1
2016-09-15 03:00:00 0
...
...
2017-01-13 01:00:00 0
2017-01-13 02:00:00 0
2017-01-13 03:00:00 0
....
2017-01-13 14:00:00 1
Then find the average of sales_at_this_hour using MySQL
EDIT: sorry not fully understand the question at first.
Use DATE_FORMAT
select
DATE_FORMAT(datetime_col, '%Y-%m-%d %h:00:00') as date,
count(id) as count
from table_name
group by date;
Get result with hours that has sales_at_this_hour > 1 (not exactly what you ask for)
datetime_col count
2016-02-04 05:00:00 5
2016-02-04 07:00:00 1
2016-02-04 08:00:00 5
2016-02-04 10:00:00 10
2016-02-04 11:00:00 1
Provide start_date and end_date, and then use DATEDIFF to calculate total time interval for the average calculation.
set #start_date = '2016-01-01', #end_date = '2017-01-01';
select
DATE_FORMAT(group_by_date.datetime, '%h:00:00') as hour,
AVG(group_by_date.count) / DATEDIFF(#end_date, #start_date) as average
from (
select
DATE_FORMAT(created_dtm, '%Y-%m-%d %h:00:00') as datetime,
count(id) as count
from table_name
where created_dtm > #start_date
and created_dtm < #end_date
group by datetime
) group_by_date
group by hour;
For each hour,
average sale count per day = total sale count / total days
hour average
01:00:00 0.03841209
02:00:00 0.01653005
03:00:00 0.0306716
04:00:00 0.01147541
05:00:00 0.01179831
I've been working on a MySQL query that sorts data into weeks but I just can't figure out how to do it.
I would like to sort the data into weeks for the current and last 11 weeks. Each week will run from Monday 00:00:00 to Sunday 23:59:59.
(Taking todays date as 2014-12-04)...
Week 1: 2014-12-01 > 2014-12-07 - (Last Monday 00:00:00 to next Sunday 23:59:59)
Week 2: 2014-11-24 > 2014-11-30 - (Monday before last 00:00:00 to last Sunday 23:59:59)
Week 3: 2014-11-17 > 2014-11-23 - (Monday before before last 00:00:00 to last last Sunday 23:59:59)
And so on...
For each week the value field data will be totalled.
I need the data returned to be in the format:
datetime: The first date (Always a Monday) of that week.
value: The total of all the values in that week.
For example, the returned data:
Week 1: 2014-12-01 : Totalled value=11
Week 2: 2014-11-24 : Totalled value=3
Week 3: 2014-11-17 : Totalled value=9
Week 4: 2014-11-10 : Totalled value=7
Table_1 data:
table1id datetime value
1 2014-09-01 06:00:00 4
2 2014-09-04 17:00:00 6
3 2014-09-09 18:00:00 9
4 2014-09-15 07:00:00 4
5 2014-09-20 10:00:00 2
6 2014-09-25 10:00:00 3
7 2014-09-30 09:00:00 8
8 2014-10-01 14:00:00 5
9 2014-10-05 10:00:00 7
10 2014-10-09 18:00:00 3
11 2014-10-15 05:00:00 4
12 2014-10-20 07:00:00 8
13 2014-10-24 16:00:00 9
14 2014-10-29 15:00:00 5
15 2014-10-31 16:00:00 7
16 2014-11-05 09:00:00 2
17 2014-11-10 08:00:00 4
18 2014-11-15 16:00:00 3
19 2014-11-20 10:00:00 9
20 2014-11-25 10:00:00 2
21 2014-11-30 10:00:00 1
22 2014-12-01 15:00:00 7
23 2014-12-04 18:00:00 2
I 'could' just pull all the data unsorted for the date range using PHP and sort it from there but I'd rather the MySQL server do it.
Any suggestions would be greatly appreciated. :-)
based on generate days from date range
you can do smething like that:
select mondays.week, mondays.day, sum(value)
from
(select a.a+1 week, curdate() - WEEKDAY(curdate()) - INTERVAL (7*a.a) DAY as day from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10 union all select 11) as a) as mondays,
Table_1
where Table_1.datetime between mondays.day and (mondays.day + interval(7) day)
group by mondays.week, mondays.day;