views:

319

answers:

6

I wonder if anyone has come across this issue before.
I have a string converted to a date and sorted ascending. The date is sorting numerically but it is not sorting on the month. I wonder if anyone has had this issue and can shed some insight as to how to get the date to sort correctly.

SELECT
  u.url_id, 
  url, 
  title, 
  description, 
  pub_date, 
  DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%d.%b.%Y') AS pub_date,
  pub_date AS sortdate 
FROM 
  urls AS u, 
  url_associations AS ua 
WHERE
  u.url_id = ua.url_id 
  AND ua.url_category_id=$type
  AND ua.approved = 'Y'
ORDER BY
  sortdate DESC

The above is the code and it works but the date isn't sorting eg it sorts like this:

 29-may-2009
 28-may-2009
 27-may-2009
 02-june-2009
 01-june-2009
A: 

Try

"SELECT u.url_id, url, title, description, pub_date, DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%d.%b.%Y') AS pub_date, pub_date AS sortdate FROM urls AS u, url_associations AS ua WHERE u.url_id = ua.url_id AND ua.url_category_id=$type AND ua.approved = 'Y' ORDER BY pub_date DESC";

The problem is you have

 pub_date AS sort_date

inside the query, and so when you sort by sort_date you sort by the string. Replace the sort order by

ORDER BY pub_date DESC

and everything should work.

Nathaniel Flath
Hi Nathaniel, I am using this current syntax but it won't sort the date month descending.//"SELECT u.url_id, url, title, description, pub_date, DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%Y.%m.%d') FROM urls AS u, url_associations AS ua WHERE u.url_id = ua.url_id AND ua.url_category_id=$type AND ua.approved = 'Y' ORDER BY pub_date DESC";// Thank you for your help
Ddywalgi
The problem is that you are now selecting just pub_date, which is a string. If you use this query, you should ORDER BY u DESC.
Nathaniel Flath
+4  A: 

I have had similar issues. What I have done (and only using ORACLE) is use the date_format in your orderby instead of the already formatted date.

so in your order by use:

DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y') DESC

or - which will first order by year

DATE_FORMAT(STR_TO_DATE(pub_date, '%Y-%b-%d') DESC
northpole
That's still going to be sorting by a *string* instead of by a *date* though, isn't it?
Jon Skeet
unfortunately, I only have access to ORACLE today so I can't verify, however, in ORACLE I just tested and it works properly with the to_char (created_dt, 'dd/MON/yyyy'), which also returns a string. The limitation is it does the days, then months. You could always break it out even further with an additional date_format string in the order by to futher order the months
northpole
or you could even switch your order by to year/month/day order by the year first.
northpole
... or you could just get it to order by date rather than a string field, couldn't you? :) That's my plan, anyway...
Jon Skeet
Jon, absolutely, I would normally order by a date which would be the best solution in my opinion and why I +1 your response.
northpole
+1  A: 

It looks like "pub_date" is a string field? If so you would need to convert it to datetime for sorting to work as expected.

William Edmondson
+1  A: 

You are telling the query to sort on the converted string, which means that it is doing sorting on a string and not a date. Try ordering by pub_date instead.

Matthew Jones
It looks like pub_date is a string anyway, given the call to STR_TO_DATE...
Jon Skeet
Arrgh. You are correct as always, grand sir. And you beat me to my revised answer. I see why there are entire questions devoted to your awesomeness. http://stackoverflow.com/questions/305223/jon-skeet-facts
Matthew Jones
+4  A: 

Okay, I was a bit confused before. Your original query is somewhat confusing as you're selecting pub_date in the list of columns, and then a conversion also as pub_date. However, you were then sorting by the pub_date column (effectively, given sortdate as pub_date) - which appears to be a string column.

Your ordering should be on the column after conversion to a date, but before conversion to a string:

SELECT
  u.url_id, 
  url, 
  title, 
  description, 
  pub_date,
  STR_TO_DATE(pub_date, '%d-%b-%Y') AS sortdate,
  DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%d.%b.%Y') AS formatted_date
FROM 
  urls AS u, 
  url_associations AS ua 
WHERE
  u.url_id = ua.url_id 
  AND ua.url_category_id=$type
  AND ua.approved = 'Y'
ORDER BY
  sortdate DESC

Note that I've renamed the "formatted" version to formatted_date. It's not clear whether you still need to select the original pub_date or not. It's possible that the formatted_date bit could be:

DATE_FORMAT(sortdate, '%d.%b.%Y') AS formatted_date

but I'm not entirely sure. I'd hope that the query optimizer would figure that out anyway.

Does your pub_date column really have to be a string? Why not keep it as a more appropriate type in the database to start with, to avoid all the parsing?

Jon Skeet
Thank you, this has worked, I had to alter it slightly by dropping the AS Formatted_date. This is the working code - "SELECT u.url_id, url, title, description, pub_date, STR_TO_DATE(pub_date, '%d-%b-%Y') AS sortdate, DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%d.%b.%Y') FROM urls AS u, url_associations AS ua WHERE u.url_id = ua.url_id AND ua.url_category_id=$type AND ua.approved = 'Y'ORDER BY sortdate DESC";
Ddywalgi
Thank you, the date is a javascript drop calendar picker which passes a hidden string to the database. I am now trying to convert the date to a format that an RSS will validate. Thank you so much for your help. I am fairly new to this and the dates have me spinning. Thanks again Jon and everyone who posted, you have all been of great help.
Ddywalgi
Then what's the DATE_FORMAT value coming out as (in terms of a column name)? My SQL-fu is fairly weak, but I can't see why it would fail with a name...
Jon Skeet
The Date format is passed as a string eg 29-MAY-2009. I have this added to the database in the column pub_date from the JS picker "date". I have it as a string because I honestly couldn't figure a way of passing it as a date to MySQL when I set it up. The extra STR_DATE you have added solved my date sorting error. Thank you.
Ddywalgi
This answer gave me the idea I needed to fix a related problem. Thanks!
Eric Ness
A: 

You want to sort like this..

ORDER BY DATE_FORMAT(STR_TO_DATE(pub_date, '%d-%b-%Y'), '%d.%b.%Y')

But if I may, methinks you should consider changing base column from string to date - lots of reasons: scalability, performance, maintainability, data integrity, yada yada yada.

Raj More