MySQL - sum data by day intervals - mysql

I have such data in my table:
I need to calculate "Paid" field of UserID which reoccurs in 7 day intervals. In this example I will SUM(Paid) for UserID "01" because it occurs 2 times in 7 days interval.
I can calculate it programmaticaly, but only in such date intervals (2016-01-01 - 2016-01-07; 2016-01-07 - 2016-01-13; etc.).
Maybe there is some possibility to perform this calculation at MySQL level in any 7 day intervals? For example: 2016-01-01 - 2016-01-07; 2016-01-02 - 2016-01-08; 2016-10-10 - 2016-10-16; etc.

I believe the method WEEK() returns the week number based on the calendar year, meaning that for 2016: 1st Jan, 2nd Jan and 3rd Jan would return 0, but 4th Jan would return 1, which to my understanding does not fit the requirements.
I would suggest:
SELECT `UserID`, SUM(`Paid`) FROM `table` GROUP BY DATEDIFF(`Date`, (SELECT MIN(`Date`) FROM `table`)) DIV 7, `UserID`

Related

grouping data in SQL based on date manipulations

I've sample data here (date: yyyy-mm-dd format)
Headquarter date Sales monthyear
1 2020-10-30 1000 202010
1 2020-10-31 500 202010
1 2020-11-01 1000 202011
1 2020-11-02 2000 202011
1 2020-11-03 3000 202011
1 2020-11-04 1000 202011
1 2020-11-05 1000 202011
I have to sum all the sales values from 2nd of current month to 2nd of next month. Grouping by headquarter and monthyear. So if I run the query, based on current_date(), the sales value should be added to that month respectively.
To brief my explanation, here's the desired result
headquarter sales monthyear
1 4500 202010
1 5000 202011
So here 30th, 31st of Oct and 1st, 2nd of Nov falls in my condition and their values are summed to oct month. But 3rd, 4th of Nov values are summed to Nov month. Likewise it happens with every month.
If I run the sql query, as today is 1st Nov (IST), today's value should be added to previous month.
I'm looking for some help in making the SQL query here.
GROUP BY DATE_FORMAT(`date` - INTERVAL 1 DAY, '%y%m')
MySQL offers the year_month specifier for extract(). I assume you want everything from the 2nd of one month to the first of the next month. If so, subtract one day:
select headquarter,
extract(year_month from date - interval 1 day) as yyyymm,
sum(sales)
from sample
group by headquarter, yyyymm;

How to get specific date interval for every month in MySQL 5.7

I want to calculate some percentage etc. between 1st and 13th of every month.
Like JAN 1st to JAN 13th Do some calculation. Similarly for every month I have to make the calculation for the first 13 days. How to get the first 13 days or any number of days in MySQL?
Assuming that you have a column of date data type it could be like this:
SELECT MONTH(date_column) AS mnth,
SUM(etc) AS col1,
SUM(etc2) AS col2
FROM tbl
WHERE DAY(date_column) BETWEEN 1 AND 13
GROUP BY MONTH(date_column)

Mysql: select timestamps between 22th of january and 3rd of february, any year

I need to compare sales in a period of days, across several years in my databases.
So I need to select rows with a timestamp that is in the range 22th january to 3rd february. The year can be anything.
How to do this?
example table sales:
timestamp sales_amount
2012-01-22 16:28:01 78
2012-10-11 16:28:06 90
2014-02-01 16:28:06 27
Select should get row 1 and 3, and exclude row 2 since its not between the specified days.
Try this
SELECT * FROM the_table WHERE DAYOFYEAR(`the_date_column`) BETWEEN 9 AND 34
This does not always work, but works for your required date range, because DAYOFYEAR of any date in that range is always fixed regardless of year.
As a general solution, you can play the trick, that you set the year to a specific one. For example:
select * from t
where str_to_date(date_format(timestamp, '1970-%m-%d %H:%i:%s'), '%Y-%m-%d %H:%i:%s')
between '1970-01-22 00:00:00' and '1970-02-03 23:59:59';

MySQL query results with weekday between 2 dates

I need a query to get results from a table that has 2 columns
Column startdt (datetime), Column enddt (datetime)
there are some records with startdt 2013-07-19 and enddt 2013-07-29
I need to get the records with weekday = 1 (Tuesday)
the record with date 2013-07-19 is weekday 4 and ends 2013-07-29 which is 0
Actually i want to get the results that has for weekday Monday or another weekday.
You can check the above link for an example
http://sqlfiddle.com/#!2/a80ce/1
If you don't understand what i want to do let me explain. I have an event that starts July 15 and ends July 25. (Starts Monday and ends Thursday) The user selects one of the week days (Monday, Tuesday etc). If he select Tuesday then i want the query that will get all events that are active in Tuesday.
I already found the answer so if anyone want to check it
SELECT articleid,startdt,enddt,dayofweek(startdt), DATEDIFF(enddt,startdt) datedf
FROM events
WHERE (dayofweek(events.startdt) <= 3 AND dayofweek(events.enddt) >= 3)
OR DATEDIFF(enddt,startdt) >=6
(3 is the number of the weekday "Tuesday")
How about using the comments that other people gave you and use a query that combines both dayofweek and a simple greater/smaller/equal syntax as follows:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6
This gives the following results if the user specified a friday (= 6):
ARTICLEID STARTDT ENDDT
4 July, 12 2013 00:00:00+0000 July, 26 2013 00:00:00+0000
6 July, 16 2013 00:00:00+0000 July, 20 2013 00:00:00+0000
I do think that you are better of using dayofmonth however as this (maybe just to me) makes it clearer, possibly combining the use of both to ensure that it's active on a friday.
The OP indicates that events which are in the history should also be retrieved and as such the following query does what he wants:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6 OR DATEDIFF(enddt,startdt) >=6
How about this solution:
first you convert the day of week in format that 6 is Saturday and 7 is sunday(it's easier for me)
if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
after that you calc the days from the start_date needed to reach some of the weekdays
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
finally you make sure that the difference in days between the two dates is no less that the above calculation
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1) <= datediff(o.end_date, o.start_date)

Cumulative monthly reporting

I have a MySQL table of photovoltaic electricity generation data (pvdata) from which I need to produce a monthly summary table. A simplified table is shown:
id date time pvdata
1 2012-01-01 10:00 50
1 2012-01-31 12:00 60
1 2012-02-10 13:00 70
2 2012-02-08 10:00 12
2 2012-03-20 10:00 17
The monthly summary table needs to show the cumulative generation for all systems in the database, regardless of whether I have received data for that month, so for example month 3 below contains the total generation from id = 1 (data received in month 2).
Also there may be more than one data point for an id in the same month, so the report must report the max(data) for the month.
year month cum_data
2012 1 60
2012 2 82
2012 3 87
I am pretty new to this, so have struggled for a while. The best I can come up with shows the cumulative total for the month, but without including the cumulative total for ids for which there is no data in the current month:
CREATE TEMPORARY TABLE intermed_gen_report
SELECT year(date) AS year, month(date) AS month, id, max(pvdata) AS maxpvdata
FROM pvdata
GROUP BY id, year(date), month(date)
ORDER BY year(date), month(date);
SELECT year, month, SUM(maxpvdata) AS cum_data
FROM intermed_gen_report
GROUP BY year, month
ORDER BY year, month;
Giving:
year month cum_data
2012 1 60
2012 2 82
2012 3 17
I think the problem is one kind of like this http://www.richnetapps.com/using-mysql-generate-daily-sales-reports-filled-gaps/ - you will want to create a table (possibly temporary) with dates (or year / month values). However that example leaves zeros where there is no data - I think you will want to do a join on a subselect that returns the most recent data before that date (or year/ month value).
I agree I think with what Aerik suggests. You will want to join your data of what is usually called a 'date dimension table'. You can find lots of examples on how to populate said table. This is a common technique in data warehousing.
You can also do what you need in one select using sub selects. Take a look at some of the previous threads like: generate days from date range