Differences in weeks between PHP and MySQL - php

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

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

MySQL grouping by season

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.

Replace DAY at end of Date

I have a column in MySQL stored as: 2014-03-16 (for March 16, 2014). It has been decided that the fields should all be changed to the first day of the month -- whatever months in which they occur. I have records that span from 1998 to present day, several thousand of them. Is there an easier way to change just the DAY (in this case, 16) on all the records besides REPLACE 2014-03-16 with 2014-03-01?
I am using PHP, so if it's easier to change it there let me know.
You can do it using a MySQL query:
UPDATE your_table
SET date_column = DATE_FORMAT(date_column ,'%Y-%m-01')

Search for age in php

I am trying to build up a search function, which gets the results by an age range. The database containts the birthday of an user (e.g. 1980-09-11 00:00:00). Now I am trying to search for users e.g. by using $agefrom = 15; and $ageto = 18;.. But I do not now how the php code and the db statement should look like..
I want to make the most stuff in php and then only do a sql query like (birth < birth_to AND birth > birth_from)..
Thank you for your help!
The simplest query, which won't work with total accuracy would be
SELECT ...
FROM ...
WHERE YEAR(birthday) BETWEEN (YEAR(now()) - 18, YEAR(now()) - 15)
This will fail if a person's birthday has not yet occured in a particular year (e.g. it's May 1st, and their b-day is June 15th). Handling that case will require a bit more date math to check for "year is right but day/month is wrong".
I would think it's easiest to construct the dates you need as 15 and 18 years ago (in PHP), then place those in the query with a BETWEEN statement. Round to midnight or you'll get bad edge cases.

Splitting into quarter with php and mysql

I have some blogposts and I want to create a link of archives.
The link will go to a page that will only return results from a particular quarter, how do I do this with php and mysql?
So I have a "date" field in a table and only want to return results from this quarter - e.g. the link to Quarter one will only return results from 1 Jan - 30th March.
I could do this with a set of static queries and dates but I would like to do it a more programmatic way.
Edit: You're talking about quarters of a year, not a quarter (1/4) of the result set.
Step 1: This depends on how your year is split up. (fiscal/etc)
Step 2: Use a WHERE clause that filters for the right months. Some variation of Date_Format().
SELECT * FROM <table>
WHERE Date_Format(date_stamp,'%Y-%m') IN ('2010-10','2010-11','2010-12')
Of course, you'll want to do some PHP to determine the months you need in place of the hard-coded month strings. But, that should get you where you need to be for a quarterly report. The reason I'm not saying use QUARTER(date) (which returns 1 - 4) is because sometimes your quarter needs to be customized, and the more generic, home-rolled mechanism is far more customizable. (And, you haven't said what quarter system is needed.)
Note: You can also use this sort of technique to do a grouping if you want a summary (total/avg/etc) on some field that's in the group as well.
This is the code I used:
$quarter = $_REQUEST['quarter'];
$quarter_conf = array(1=>"('2011-01','2011-02','2011-03')", 2=>"('2011-04','2011-05','2011-06')",3=>"('2011-07','2011-08','2011-09')", 4=>"('2011-10','2011-11','2011-12')");
$sql = "SELECT * FROM table where Date_Format(`date`,'%Y-%m') IN ".$quarter_conf[$quarter]." ORDER BY `date` DESC";

Categories