Order by date (varchar)? - mysql

I want to order by date.
e.g.
table_date
February 2011
January 2011
December 2010
I've already tried:
SELECT distinct(table_date) FROM tables ORDER BY table_date DESC
bur it doesn't work.
I get this instead:
January 2011
February 2011
December 2010
Can you help me please?

If you must store the dates in a varchar which as others pointed out is not recommended, you could use:
SELECT table_date FROM tables ORDER BY STR_TO_DATE(table_date, '%M %Y') DESC;

If you want to order by date, store it as a date, not a string. Unless your date string is of the form yyyy-mm-dd, it will not sort as you want it.
Databases are hard enough work as-is, without people making it harder, and you should be striving as much as possible to avoid what I like to call SQL gymnastics.
Store it as a date then, if you must, use date functions to get it in the form February 2011.
It'll be a lot easier going that way than what you're trying to do.
Even if you can't change any of the current columns due to code restrictions, you can always add another column to the database like TABLE_DATE_AS_DATE and put in an insert/update trigger to populate it based on TABLE-DATE.
Then just do:
update table x set table_date = table_date
or something similar, to fire the trigger for all rows.
Then, your query can still get at table_date but use table_date_as_date for ordering. That's a kludge of course but I've had to use tricks like that in the past when it was imperative the code could not change, so we had to resort to DBMS trickery.

Store dates as DATE, not as VARCHAR, that's a huge mistake. Use STR_TO_DATE() to convert your content. When you're done, you can order by dates without any problems.

Date should be stored as date and not VARCHAR.
Suppose you have table_date in the following format (DD-MM-YYYY)
table_date
2011-01-01
2011-02-01
2010-12-01
Now you can perform order by clause in the following way
SELECT * FROM table_order ORDER BY str_to_date(date, "%Y-%M-%D") ASC
I doubt if the output will be in ordered form

Related

mysql Search range by year

I want to get the date of birth of a cat as a range of years.
The year range is as follows, and several selections are possible.
Year : [2000, 2010, 2020]
If I select 2020, the period from 2020-01-01 to 2029-12-31.
If I select 2000, 2020, the period from 2000-01-01 to 2009-12-31 and 2020-01-01 to 2029-12-31.
<TABLE>
CAT {
ID number,
Birth DateTime,
...
}
I have searched for various ways through books and Google, but I can't find the way I want to do so..
select * from CAT
where birth between '2000-01-01' and '2009-12-31'
or birth between '2010-01-01' and '2019-12-31'
or birth between '2020-01-01' and '2029-12-31'
I tried to use 'Between' or '-01-01', but if [2000, 2020] is selected, it must be connected with 'or'.
The more or, the slower the speed.
Please tell me a good way to do range calculations being able to use index.
The index is being used for BirthDate.
Add) In my db, the query of 'SUBSTRING(YEAR(CAT.birth),1,3) IN (200,202)' works quickly.
I have 500,000 data, can I use it like this?
All you need to do is add index to column birth and run your query above with BETWEEN and OR.
if you are using mysql, did you tried with YEAR() function ?
Example:
SELECT * FROM cat WHERE YEAR(birth) BETWEEN 1990 AND 2018 ORDER BY YEAR(birth) ASC;
Please check this Mysql YEAR()
If you expect to get more than about 20% of the rows from a table, then an INDEX will be eschewed for simply scanning all the rows.
Otherwise, having INDEX(birth) will help with certain queries, but none of the ones mentioned so far. Each of them is not "sargable" .
To use the index (and be efficient for a limited range of years or date range), something like this is probably what you need. This example covers 2 calendar years.
WHERE CAT.birth >= '2018-01-01'
AND CAT.birth < '2020-01-01'
BTW: SUBSTRING(YEAR(CAT.birth),1,3) can be simplified to LEFT(CAT.birth, 3), but that still cannot use the recommended index.
BTW: A 'bug' in your code: Since birth is a DATETIME, and '2009-12-31' excludes but midnight of the morning of New Year's Eve. Note how I avoided this common 'bug' by using < and the next day. This works whether you have DATE, DATETIME or DATETIME(6), etc.

Proper datatype for month in mysql

I want to store month like JAN,FEB and soon in database. What datatype should I use? because if I use varchar, when I display it, it won't sort properly. Please advise.
You can use TINYINT is as the month and have another table with columns month_id, Month_name
where you place
1 JAN
2 FEB
etc...
the sorting etc will work fine. when you want to display, have a simple inner join.
Just store it as a complete date (perhaps always using the first as the day) and use the database functions MONTH() if you only need part of it. This makes using that field much easier as you can still do range queries, etc.
Store months number in database.
i.e. For JAN store 01, FEB store 02 and so on..
Take Datatype TINY INT for your field.
OR another solution you can try:
Take datatype DATE for your field.
Use this type of query: SELECT DATE_FORMAT('2014-03-27','%b');
DATE_FORMAT_MYSQL

SQL: DATE_FORMAT() and order

What is wrong here? I want to change format of date and then order it (I use MySQL):
SELECT * FROM changes ORDER BY DATE_FORMAT(`when`,'%e %c'), `class`, `hour` ASC
I want to change format of date and then order it
Probably not. You probably want to order by date. It's not clear whether you want to include the formatted date in your SELECT clause, but I'll assume you do.
SELECT *, DATE_FORMAT(`when`,'%e %c') as formatted_date
FROM changes
ORDER BY `when`, `class`, `hour` ASC
You will find that date_format(%e %c) will be converting a numeric field (in this case month and day) into a varchar, but will not be including leading 0s. This is going to cause issues in sorting as %c will convert September to 9 and October to 10, which will mean September will actually appear as a later date (the first character, 9, is greater than 1). This is also the same problem with %e as the 3rd of the month will appear after the 20th etc.
Easiest answer is not converting your dates into a varchar and allowing the sorting to function as a date, or prepending leading 0s to both the day and the month. In your comment you say you wish to sort "by the months and then days" and "my dates are always in the same year". A normal date would be sorted by year/month/day, so assuming the years are the same (which you say), and then you wish to sort by the month and then days, a normal date sort should suffice without any conversion. If this is not the sort order you require, perhaps you need to clarify, or provide some example data with what you want to see.
If for some reason you do want to sort by day and then by month (1 January, 1 February... 2 January, 2 February ...) you could use date_format(%d %m) which is the same as your original code, except will include leading 0s and enable a sort to function correctly.

Sort Date in Mysql table in DESC order

I want to show date column in DESC order where date is entered as VARCHAR and is in order 20-JUN-2007 I have already used ORDER BY RIGHT(vPublishedDate, 4) but it doesn't effect the month and date
Here is one way to do it using STR_TO_DATE (take into account the other answers about converting the column to date, although you may not have control over the database):
SELECT ...
FROM ...
ORDER BY STR_TO_DATE(vPublishedDate,'%d-%M-%Y')
As an example:
SELECT STR_TO_DATE('20-JUN-2007','%d-%M-%Y') as Date;
+------------+
| Date |
+------------+
| 2007-06-20 |
+------------+
Why are you using a VARCHAR to store a DATE? Use a DATE to store a DATE and then, as if by magic, sorting works all on its own.
You really should be storing dates as dates, not character-type fields. Then you wouldn't need to worry about this sort of "SQL gymnastics" (as I like to call it).
Databases are for storing data, not formatting.
By forcing yourself to manipulate sub-columns, you basically prevent the database from performing any useful optimisations.
In order to do what you want with the data you have you have to do something like:
use substring to extract individual sub-column information to get them in the order you want; and
use some sort of lookup to turn a string like "NOV" into 11 (since the month names will sort as DEC, FEB, AUG, APR, JAN, JUL, JUN, MAR, MAY, NOV, OCT, SEP).
And this would be a serious performance killer. Now there may be a function which can turn that particular date format into a proper date but I urge you: don't use it.
Set up or change your database to use an intelligent schema and all these problems will magically disappear.
It's a lot easier to turn a date column into any sort of output format than to do the same with a character column.
Change that VARCHARto a Date type column, if you can.
You can also try this, although this is NOT the RIGHT approach.
Select STR_TO_DATE(your_date_column,'%d/%m/%Y') AS your_new_date from your_table order by your_new_date DESC
Try converting the varchar to date using str_to_date and then you can apply the sorting logic.
I would suggest you to change the type as Date.
Then run a script which converts your dates to the correct DB format.
Sorting would be then be just as simple as sorting ids in MySql

mysql getting all possible months from datetime field

so i have a table with hundreds records. And a have a filed name "created" type with a datetime format. Now I want to make and archive with the months. For example January, February.... etc. I need to create query to find all possible months. For example if my records start from 2011/05/01 to now I will need to fetch the months that means months 5,6,7,8,9,10,11,12.
Is there a way to that ???
If you are looking at the list of all Months present in the created field (as I understand your query) then do this:
SELECT DISTINCT(MONTH(created)) FROM posts;
The resulting set would be the list of unique months in the field. If this will complain then try:
SELECT DISTINCT(MONTH(DATE(created))) FROM posts;
You can then substitute MONTH for MONTHNAME and get names instead. I did not add the WHERE clause to these queries but you can limit the dataset you are looking at as you see fit.
For more information take a look at http://dev.mysql.com/doc/refman/5.1/en/functions.html this has a list of quite a few functions that MySQL natively provides.
Yes, use the DATE_FORMAT function and other date and time functions.
More details here
For example, if you want all your records for December 2011:
SELECT * FROM posts WHERE YEAR(created) = 2011 AND MONTH(created) = 12