The .NET code, DateTime.Now.ToString() outputs something like this:
11/28/2011 1:17:05 PM
I store it in MySQL as a VARCHAR.
When I SELECT it back to my DataTable, I would like it to be ordered. Of course since it's a VARCHAR, a simple ORDER BY will sort it alphabetically and not chronologically.
Is there a way to ORDER BY this chronologically, using SQL?
You will want the STR_TO_DATE function
SELECT columns
FROM table
ORDER BY STR_TO_DATE(varCharDateColumn, '%m/%d/%Y %h:%i:%s')
Related
I wish to sort my table with date order so that recently added data will be on the top of the table.
I have used query for sorting as:
select date from register_table order by date desc.
Currently table display data as:
date
02.04.2019
05.04.2019
09.04.2019
10.04.2019
06.02.2019
23.01.2019
11.01.2019
I expect my table to display as:
date
10.04.2019
09.04.2019
05.04.2019
02.04.2019
06.02.2019
23.01.2019
11.01.2019
How to display data in date order?
Your fundamental problem is not storing the date as a date. You should fix that.
For the query to work, use:
order by str_to_date(date, '%m.%d.%Y')
To fix the data, you can do:
update register_table
set date = str_to_date(date, '%m.%d.%Y');
alter table register_table
modify date date;
You can see how this works here.
I don't know why your date is stored like that but here, give this a try:
SELECT date FROM date ORDER BY STR_TO_DATE(REPLACE(date,'.','-'),'%d-%m-%Y') DESC;
If you want to see what exactly happen, run this query:
SELECT date,STR_TO_DATE(REPLACE(date,'.','-'),'%d-%m-%Y') FROM date;
In case you still don't quite understand, refer to MySQL STR_TO_DATE function and MySQL REPLACE function.
I have a mysql column where the data is stored as VARCHAR though the data values are of datetime in the format of yyyy-mm-dd hh:mm:ss.
Now my task is to group by the date part i.e yyyy-mm-dd by converting VARCHAR to date-time and then just taking date part out of it
QUERY
SELECT SUM(value)
FROM table
GROUP BY name , [date part of the varchar field]
Please let me know if this is at all possible and if yes, how?
Assuming that your data in this varchar field is properly formatted, you can work with the left function, like this:
SELECT LEFT(mydate, 10) AS myval,
SUM(myvalue)
FROM mytable
GROUP BY myval;
If this isn't a big issue; I'd advise converting your varchar column to datetime or timestamp. If not only for the possibly better data storage usage, it'll be way easier to do work with date and time related functions.
Just use the left function. You can leave the date as a string:
SELECT left(datecol, 10) as YYYYMMDD, SUM(value)
FROM table
GROUP BY left(datecol, 10);
I removed name from the group by because it doesn't seem relevant to the question. You can, of course, add it back in.
By the way, MySQL understands this format for dates, so if you really, really want a date:
SELECT date(left(datecol, 10)) as RealDate, SUM(value)
FROM table
GROUP BY RealDate;
Help! One column in my database is for dates. All of my dates are unfortunately in the String form (YYYY.MM.DD). I have a MASSIVE database (300+GB) so ideally would like to avoid transformations.
Is there a way I can select rows for dates in between YYYY.MM.DD and YYYY.MM.DD? What would the script look like?
Thank you!
If the months and days are stored with leading zeroes, the BETWEEN operator will work as expected. So will ORDER BY.
create table your_table (
date_value varchar(10) not null
);
insert into your_table values
('2013.01.01'), ('2013.01.13'), ('2013.01.30'), ('2013.01.31'),
('2013.02.01'), ('2013.02.13'), ('2013.02.28'), ('2013.02.31'),
('2013.03.01'), ('2013.03.15'), ('2013.03.30'), ('2013.03.31');
select date_value
from your_table
where date_value between '2013.01.01' and '2013-01-31'
order by date_value;
2013.01.01
2013.01.13
2013.01.30
One of the main problems with your structure is that you lose type safety. Look at this query.
select date_value
from your_table
where date_value between '2013.02.01' and '2013.02.31'
order by date_value;
2013.02.01
2013.02.13
2013.02.28
2013.02.31
If you'd used a column of type date or datetime or timestamp, the dbms would not have allowed inserting the values '2013.02.31', because that's not a value in the domain of date. It is a value in the domain of varchar. (And so is "Arrrrgh!", unless you've got a CHECK constraint on that column that severely restricts the acceptable values.)
Not good solution, but works (cost much performance).
You have formated date in order year, month, day (good order to compare strings, without transformation to datetime), so you can try
SELECT * FROM Table WHERE StringDate > '2013.07.10' AND StringDate < '2013.07.14'
It returns bad results if there are dates before year 1000 without leading zero ('999.07.14').
But I dont know how it works on big database.
SQL Fiddle
Between in SQL is inclusive of both bounds. If that is what you want, you can just use between:
where col between 'YYYY.MM.DD' and 'YYYY.MM.DD'
Where the two constants are whatever values you are looking for.
If you have an index on the column, then between (as well as >, >=, and so on) will use the index. You do not need to transform the values. If your constants are dates of one form or another, then you can use date_format() to create a string in the right format. For instance, to get dates within the past week:
where col >= date_format(adddate(now(), -7), '%Y.%m.%d')
I am working with a MySQL database where dates are stored as varchar like this:
'2013-01-31' in column cl_223
I need to select only records from 2013 so I tried:
SELECT ..
FROM ....
Where cl_223 Like '2013'
But that does not seem to work.
Thanks for all help!
You must add % as a wildcard :
SELECT ..
FROM ....
WHERE cl_223 LIKE '2013%'
Storing a datettime value in a varchar column complicates some functionality on date time operations. But of course you can select your values writing such a query as follow
SELECT * FROM table_name WHERE cl_223 LIKE '2013%'
But if you don't have any performance issue you can convert the varchar column to a datetime value and write stronger typed query like this:
SELECT * FROM table_name WHERE STR_TO_DATE(cl_223,'%Y-%m-%d2') BETWEEN '2013-01-01' AND '2013-12-31'
But if you need a date time value as a date time in your process you'd better store it in a datetime column instead of a varchar column.
The query should be
SELECT ..
FROM ....
Where cl_223 Like '2013%'
However, the better solution would be to store the dates as DATE data types. If the dates in that column are always used in the format they're in now, the change would be backwards compatible. It would also allow for easier processing of the date values.
I'm trying to make some vchar values searchable based on a date.
The strings I have to work with look like this:
1/7/2006 12:45:24 AM
1/7/2006 1:18:36 AM
1/7/2006 1:21:43 AM
1/7/2006 1:32:09 AM
3/30/2006 12:32:10 PM
3/30/2006 1:19:30 PM
3/30/2006 1:20:44 PM
So first off let's get rid of the AM.. PHPMyAdmin the sql query is:
SELECT trim('AM' FROM `orderdate`) FROM tblorders
This works to get rid of the AM now let's set the values as a variable and try to wrap a string to str_to_date() around the results:
SELECT trim('AM' FROM `orderdate`) AS `value`, STR_TO_DATE(`value`,'%d,%m,%Y') FROM tblorders
This yields value as an unknown column. How else do you string two function values together so as to then use them to be filtered such as WHERE value > 2/1/2006 ?
You can compose functions like this:
select str_to_date(trim('AM' from orderdate), '%m/%d/%Y')
Note that I also corrected your date format to match your data. You don't actually need to trim those values to use str_to_date on them, just this will work fine:
select str_to_date(orderdate, '%m/%d/%Y')
If you want to use that in your WHERE clause then put the function calls in there:
select trim('AM' from orderdate), str_to_date(orderdate, '%m/%d/%Y')
from your_table
where str_to_date(orderdate, '%m/%d/%Y') > '2006-01-02'
and let the optimizer recognize the repetition or use a derived table:
select value, the_date
from (
select trim('AM' from orderdate) as value, str_to_date(orderdate, '%m/%d/%Y') as the_date
from your_table
) dt
where the_date > '2006-01-02'
Note the use of ISO 8601 dates in the query, that format is unambiguous and any database worth using will understand it regardless of your locale settings.
I'd also recommend that you fix your schema to use real timestamps instead of those strings.