Dates functions with MySQL and unix timestamp

MySQL has powerful functions built in to manipulate data with dates. These functions only work within MySQL providing your using their own date/time stamp. If your like me, your much rather use the PHP function time() to get the Unix timestamp and store that in the database. It seems a shame to miss out on these features because we use Unix time. Never fear, the following examples shows how to get round this using FROM_UNIXTIME(). So what happens now if we want to SELECT or GROUP data by periods, such as by week, month or year. Take one look in the MySQL manual and there are few practical examples on how this can be done using only the Unix timestamp. Below I run through a practical example and how this can easily be achieved. If you want a mock up table to try it out, run the following SQL. This table is a vastly simplified version of a e-commerce system order table, but the logic here could be applied to any type of database driven web site.

CREATE TABLE `orders` (
`order_ID` int(11) NOT NULL AUTO_INCREMENT,
`timeordered` int(11) NOT NULL DEFAULT '0',
`grandtotal` double(10,2) NOT NULL DEFAULT '0.00'
PRIMARY KEY  (`order_ID`)) ;

This table contains the Unix timestamp in `timeordered` and `grandtotal` contains a decimal number. We are going to construct a SQL query that will list the number of orders in a month, the total amount of all those orders and the average value of those orders. Lines 1, 2, 4 are standard functions used to calculate our values. The interesting lines are 5 and 6. If I was using the normal MySQL timstamp and could simply write GROUP BY MONTH(), YEAR() to achieve the results we want. You may ask why are we using both MONTH() and YEAR() when we just need it to group by MONTH(). Well the answer is you could just use MONTH(), but that would only ever return 12 rows (1 for each month) no matter over how many years. So for example it would group January 2004, January 2005 or any other January. For some systems this would be undesirable. Using YEAR() ensure only one month and one year is in one return row.

SELECT COUNT(order_ID) AS `number`,
SUM(grandtotal) AS `cgrandtotal`,
FROM_UNIXTIME(timeordered, '%M %Y') AS `fdate`,
AVG(grandtotal) AS `averagegrand`
FROM `orders`
GROUP BY MONTH(FROM_UNIXTIME(timeordered,'%Y-%m-%d %H.%i.%s')),
YEAR(FROM_UNIXTIME(timeordered,'%Y-%m-%d %H.%i.%s'))
ORDER BY timeordered DESC

Normally we put the column name in the brackets of the function of the MySQL date (ie YEAR(column-name)). But because we are using Unix time we must use the function FROM_UNIXTIME(column-name-of-unixtime, format). The format parameter simply specifies how to turn the Unix time to a understandable timestamp for MySQL, the ones shown on lines 7 and 8 seem to work fine, I believe there may be shorter ones that can be used.

So the query above will return something like this (after adding your own dummy data!):

number cgrandtotal fdate averagegrand
8 532.00 January 2008 66.50
21 1201.20 December 2007 57.20
17 1041.25 November 2007 61.25

The example below assumes you have some basic knowledge of SQL and has been tested on MySQL 4.1.

4 Responses to “Dates functions with MySQL and unix timestamp”
Christopher Hill Posted on 20 February 2008 at 10:43 pm

A nice query. One thing I would be interested in seeing is how this query handles a database with millions of rows — would you be interested in putting that kind of test together?

Just to note, you say you like to use time(), but for non-essential timestamps it is better to use $_SERVER['REQUEST_TIME'] due to it being faster.

Paul Posted on 22 February 2008 at 11:14 am

A very good idea, i will in time put a test together and see how a query like this performs. I currently implement this in a database VIEW.

The problem with $_SERVER[’REQUEST_TIME’] if you want to do any operations on it has to be converted back to unix time. Surely this is only for a human readable value, i think i would only store a unix time if it was going to be used in application.

mantosz Posted on 2 December 2008 at 10:05 pm

thank you for the article! It helps me alot

Shiro Posted on 21 August 2009 at 2:31 am

This is absolute very useful tutorial for people want to use unix timestamp to generate report. Thank you very much for your sharing~

Post a Comment