MySQL grouping by season - php

Im trying to figure out the most efficient way of calculating statistics using data from MySQL database with dates.
Currently, I use the following syntax
Example:
SELECT sum(Precipitation) from DataTable GROUP BY YEAR(Datetime)
This works perfectly fine, I get the total rainfall for each year. However, now I would like to implement the option to set the beginning of the rain season. In some places, the rain season might begin for example in September. In such case I would need the same calculation, i.e. also grouped by "years", but always since Sep to Aug.
I was thinking about how to do this and the only way I can think of would be somehow calculating the monthly sums and the using PHP try to add them up. But the problem is that that would probably be much slower given there is lots of data and the original script uses just this one line above.
Is there any more efficient way of then getting something like
2014 - xyz inches, 2015 - xyz inches, but where the 2014 would correspond for example to season 2014/2015 etc.
The data in the table is like this: column 1 is always the Datetime and then the actual value, data in 5 minute intervals. I need to maintain the table structure, so I cannot create a different table where the values would be organized differently.

Use this query:
SELECT SUM(Precipitation)
FROM DataTable
GROUP BY YEAR(DATE_SUB(Datetime, INTERVAL 8 MONTH))
This query shifts every date backwards by 8 months, with the result that September 1, 2016 would appear to be the first day of 2016, and August, 2016, would appear to be the last month of 2015.

Related

Why is MySQL current week less than PHP current week? [duplicate]

I have the following query.
SELECT COUNT(*), WEEK(date), YEAR(date) FROM myTable GROUP ON YEAR(date), WEEK(date)
Say it produces the following results
32 33 2012
43 34 2012
39 35 2012
17 36 2012
I now want to get all 39 records in week 35 of 2012. I do not, however, wish to use WEEK(date)=35 AND YEAR(date)=2012 in my WHERE clause as it does not utilize indexes. Instead, I wish to find the boundaries and use conditionals. I also do not want to use BETWEEN as rounding errors might occur.
I therefore try the following thinking all is good, but do not get 39 records. Obviously MySQL and PHP deal differently with weeks. I see that MySQL WEEK() utilizes mode 0, 2, 4, and 6 that all return a week that starts with Sunday. Ideally, I would have the one that is most commonly used by people, the most important thing is that it is the same as provided by DateTime. How would I do so? Thank you
$w=35;$y=2012; //Given
$w=sprintf('%02d',$w); //Make sure it is two digits
$date = new DateTime($y.'W'.$w);
$d1=$date->format('Y-m-d');
$date->add(new DateInterval('P1W'));
$d2=$date->format('Y-m-d');
$sql='SELECT * FROM myTable WHERE date >= ? AND date < ?';
You are on the right track with regards to how MySQL works, having various modes for week-related functions that can produce different results. http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week
It is my understanding the MySQL mode which is equivalent to PHP's date logic is mode 3, which is the ISO week date standard http://en.wikipedia.org/wiki/ISO_week_date
This has weeks starting on Mondays and weeks numbered 1-53.
So you would need to use WEEK(date_field, 3) to get PHP compatible values.
As an alternate approach, one thing I have found handy in cases where you need the ability to flexibly query on different date ranges or aggregations (Q1- Q4, H1 - H2, etc.), or where you might need to utilize different weeks than PHP supports is to use a date helper table in MySQL (similar to what one may use as a date dimension table in a data warehouse, if you are familiar with that). It can give you a convenient table to join against in order to look up date ranges. Something like this should work:
http://databobjr.blogspot.com/2012/06/create-date-dimension-table-in-mysql.html

How to select data based on months using mysql

I'm a beginner in php and making a small online banking system in php for my College project. I wanted to generate the statement for each month. I'm recording each transaction happening in each days. I wanted to retrieve rows from the table till the end of each month beginning from the starting of the account. So If I click on the view statement link, (considering that I opened the account on 14th of Feb) I need to see two statements. 1 from 14th of Feb to 28th of Feb and another one from 1st of March to current date.
What mysql query should I used to get this?
You might try appending to your current query the condition for the current month, you can -1, -2, -3, etc... to the AND MONTH... condition.
AND
YEAR(`date_column`) = YEAR(NOW())
AND MONTH(`date_column`) = MONTH(NOW())
where date_column is the name of the column you are working. It might also be that you are trying to GROUP BYMONTH(date_column)` its a bit hard to tell.

Differences in weeks between PHP and MySQL

I have the following query.
SELECT COUNT(*), WEEK(date), YEAR(date) FROM myTable GROUP ON YEAR(date), WEEK(date)
Say it produces the following results
32 33 2012
43 34 2012
39 35 2012
17 36 2012
I now want to get all 39 records in week 35 of 2012. I do not, however, wish to use WEEK(date)=35 AND YEAR(date)=2012 in my WHERE clause as it does not utilize indexes. Instead, I wish to find the boundaries and use conditionals. I also do not want to use BETWEEN as rounding errors might occur.
I therefore try the following thinking all is good, but do not get 39 records. Obviously MySQL and PHP deal differently with weeks. I see that MySQL WEEK() utilizes mode 0, 2, 4, and 6 that all return a week that starts with Sunday. Ideally, I would have the one that is most commonly used by people, the most important thing is that it is the same as provided by DateTime. How would I do so? Thank you
$w=35;$y=2012; //Given
$w=sprintf('%02d',$w); //Make sure it is two digits
$date = new DateTime($y.'W'.$w);
$d1=$date->format('Y-m-d');
$date->add(new DateInterval('P1W'));
$d2=$date->format('Y-m-d');
$sql='SELECT * FROM myTable WHERE date >= ? AND date < ?';
You are on the right track with regards to how MySQL works, having various modes for week-related functions that can produce different results. http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week
It is my understanding the MySQL mode which is equivalent to PHP's date logic is mode 3, which is the ISO week date standard http://en.wikipedia.org/wiki/ISO_week_date
This has weeks starting on Mondays and weeks numbered 1-53.
So you would need to use WEEK(date_field, 3) to get PHP compatible values.
As an alternate approach, one thing I have found handy in cases where you need the ability to flexibly query on different date ranges or aggregations (Q1- Q4, H1 - H2, etc.), or where you might need to utilize different weeks than PHP supports is to use a date helper table in MySQL (similar to what one may use as a date dimension table in a data warehouse, if you are familiar with that). It can give you a convenient table to join against in order to look up date ranges. Something like this should work:
http://databobjr.blogspot.com/2012/06/create-date-dimension-table-in-mysql.html

Caculating periods of 6 months using PHP and MySQL

Good evening.
How can I calculate periods of 6 months (semesters or a two terms years)?
Explaining:
There is a spreadsheet, which I will convert to a MySQL DB, that has the following, relevant, columns Course, Begin and Duration. Course is a string field that combined with the info from another table returns the Duration. The Begin field is year-semester (like 2010-2 is two thousand and ten secound semester) that the course was started. Duration is the number of years.
The format
table1
**Course** **Begin**
Graduation 1 2010-1
table2
**Course** **Duration**
Graduation 1 4,5
2010-1 means 2010 first semester and 4,5 (actually 4.5 years - four dot five years) means four and a half years, that gives a final date like 2014-1.
The fields format, unfortunately, come from another database which I don't have access to change, I just can import the data.
This is probably simple or extremely simple or not.
[Edit]
I hope now is correct.
[Edit]
This will be imported form a first DB, caculated and imported to another DB.
MySQL doesn't have standard support for semesters, so you'd have to convert to months first (quarters are also supported, but working with months is easier regarding date).
This means that you need to replace "2010-1" by "2010-01-01" and "2010-2" by "2010-07-01". This could be done with REPLACE($begin, '-1', '-01-01') and REPLACE($begin, '-2', '-07-01').
For each semester you could add 6 months: DATE_ADD('2010-01-01', INTERVAL 6 MONTH) will return "2010-07-01". Multiply the "duration" by 12, which will give the amount of months you need to shift the "Begin".

MySQL to calculate solar revenue with price changes according to date

I have a problem that I just cannot seem to get my head around, and hope someone can help give me some advice.
Ever since getting solar PV cells fitted on my house roof, I have been generating electricity and in accordance to some (rather generous) incentives to do this kind of thing, have been making money for every kWh of electricity I generate. Seeing this as being a bit of a database project, I set about writing some PHP/MySQL to track daily generation, and now have nearly a year's worth of daily kWh readings, which are nicely presented to me in graphical form, both in a month-by-month view, and as a yearly (grouped into months) graph.
I'm now wanting to expand the system to show revenue in monetary terms, rather than kWh of electricity. Currently, the figure is £0.454 per kWh, though this figure changes every year on the April 1st (it was £0.433 previously).
This is my current MySQL structure:
Table feedin:
year (year4) rate (float)
2010 0.433
2011 0.433
2012 0.454
Table generation:
day (DATE) reading (float)
2011-12-01 7.682
2011-12-02 5.747
2011-12-03 4.982
... ...
2012-08-13 8.022
2012-08-14 19.449
2012-08-15 5.484
My first attempt at this was all rather cumbersome with a very mixed mess of PHP and MySQL queries, with the bulk of the logic being done in PHP (my MySQL skills are "limited", at best). However, as time is going on, I see that it would be ideal if the whole thing were done in MySQL.
I've no real idea how to tackle this. My initial thoughts are that we need to select yearly chunks of data (well, date-ranges from April 1st in one year, to March 31st the next), and multiply it by the appropriate year rate. And that "appropriate year rate is the rate applicable at the start of that date range, ie, as of April 1st).
Ideally, I'd like the query to be able to cope with multiple yearly boundaries, so, for example, several years down the road, I'd like to be able to query the absolute total revenue produced to date. Ultimately, I would just like to pass the query the start and end dates, and it returns the correct figure.
Link the year of the generation date to the year of the feedin tariff
SELECT *, generation.reading*feedin.rate AS profit
FROM generation, feedin
WHERE YEAR(generation.day)=feedin.year
BUT as this must relate to year start of APRIL 1st
SELECT *, generation.reading*feedin.rate AS profit
FROM generation, feedin
WHERE YEAR(DATE_SUB(generation.day, INTERVAL 3 MONTH))=feedin.year
This will move the recorded dates back 3 months too, making them Jan-Dec instead of Apr-Mar wich will then match the feedin year
something along these lines:
select year, sum(reading) as total_generation, (total_generation*feedin.rate)
FROM feedin
LEFT JOIN generation on feedin.year = YEAR(generation.day)
GROUP BY year
Hope this does what you want (tested and working)
SELECT (a.rate*b.reading),a.year as amount from generation as b, feedin as a where Year(b.day)=a.year

Categories