SQL ORDER BY date problem - sql

Can you please help me in solving this problem. I am trying to order the results of an SQL query by date, but I'm not getting the results I need.
The query I'm using is:
SELECT date FROM tbemp ORDER BY date ASC
Results are:
01/02/2009
03/01/2009
04/06/2009
05/03/2009
06/12/2008
07/02/2009
Results should be:
06/12/2008
03/01/2009
01/02/2009
07/02/2009
I need to select the date in the format above.
Your help is much appreciated.

It seems that your date column is not of type datetime but varchar. You have to convert it to datetime when sorting:
select date
from tbemp
order by convert(datetime, date, 103) ASC
style 103 = dd/MM/yyyy (msdn)

It sounds to me like your column isn't a date column but a text column (varchar/nvarchar etc). You should store it in the database as a date, not a string.
If you have to store it as a string for some reason, store it in a sortable format e.g. yyyy/MM/dd.
As najmeddine shows, you could convert the column on every access, but I would try very hard not to do that. It will make the database do a lot more work - it won't be able to keep appropriate indexes etc. Whenever possible, store the data in a type appropriate to the data itself.

Unsure what dbms you're using however I'd do it this way in Microsoft SQL:
select [date]
from tbemp
order by cast([date] as datetime) asc

this works for me:
SELECT datefield
FROM myTable
ORDER BY CONVERT(DATE, datefield) ASC

Following answer may help you
perform your date ordering by your date identifier but use to_char() function in select clause and use some other identifier in select clause for date
e.g.
SELECT TO_CHAR(DISPDATE1,'DD/MM/YYYY') AS DISPDATE,
SUM(APPLCOUNT) AS APPLIED,
SUM(CONFCOUNT) AS CONFIRMED
FROM
(
SELECT COUNT(ID) AS APPLCOUNT,
0 AS CONFCOUNT,
STUDENT.APPLIED_ON AS DISPDATE1
FROM STUDENT
WHERE STUDENT.ID = P_ID
GROUP BY STUDENT.APPLIED_ON
UNION
SELECT 0 AS APPLCOUNT,
COUNT(ID) AS CONFCOUNT,
STUDENT.CONFIRMED_ON AS DISPDATE1
FROM STUDENT
WHERE STUDENT.ID = P_ID
GROUP BY STUDENT.CONFIRMED_ON
)
GROUP BY DISPDATE1
ORDER BY DISPDATE1;

SELECT CONVERT(char(19), CAST(date AS datetime), 101) as [date]
FROM tbemp
ORDER BY convert(datetime, date, 101) ASC

Try using this this work for me
select * from `table_name` ORDER BY STR_TO_DATE(start_date,"%d-%m-%Y") ASC
where start_date is the field name

I wanted to edit several events in descendant chonologic order, and I just made a :
select
TO_CHAR(startdate,'YYYYMMDD') dateorder,
TO_CHAR(startdate,'DD/MM/YYYY') startdate,
...
from ...
...
order by dateorder desc
and it works for me.
But surely not adapted for every case...
Just hope it'll help someone !

This may help you in mysql, php.
//your date in any format
$date = $this->input->post('txtCouponExpiry');
$day = (int)substr($date, 3, 2);
$month = (int)substr($date, 0, 2);
$year = (int)substr($date, 7, 4);
$unixTimestamp = mktime(0, 0, 0, $year, $day, $month);
// insert it into database
'date'->$unixTimestamp;
//query for selecting order by date ASC or DESC
select * from table order_by date asc;

try this
Order by Convert(datetime,#date) desc

this should work for your date format
order by convert(date, your_column, 104) desc

Casting/Converting can result in out of range exceptions that unfortunately are not always as simple as excluding nulls.
A simple alternative method, which avoids the cast, is:
SELECT date
FROM table
ORDER BY YEAR(date), MONTH(date), DAY(date) ASC;

Related

SQL select query returning wrong order by DESC

This is my query which is not returning the correct result ordered by RegistrationDate Desc:
SELECT
Team,
CONVERT(VARCHAR(10), RegistrationDate, 103) AS RegistrationDate,
FormFilledAt, CreationBy
FROM
Table_Candidate_Info
WHERE
Status = 'Completed'
GROUP BY
Team, CONVERT(VARCHAR(10), RegistrationDate, 103), FormFilledAt, CreationBy
ORDER BY
RegistrationDate DESC
If I will use this query, it's returning the correct order by RegistrationDate Desc
select *
from Table_Candidate_Info
order by RegistrationDate desc
I want above first query should be RegistrationDate order by Desc with group by query
Try
order by CONVERT(VARCHAR(10),RegistrationDate,103) desc
or better if you want really keep order by date (and not text) try this:
select Team, CONVERT(VARCHAR(10),RegistrationDate,103) as RegistrationDate, FormFilledAt,CreationBy
from (
Select Team, cast(RegistrationDate as date) as RegistrationDate ,FormFilledAt,CreationBy
from Table_Candidate_Info
where Status='Completed'
group by Team,cast(RegistrationDate as date) ,FormFilledAt,CreationBy
) tmp
order by RegistrationDate desc
Note: if you want group by date + time remove cast… as date
use distinct and CONVERT(VARCHAR(10),RegistrationDate,103) in order by clause
Select distinct Team,CONVERT(VARCHAR(10),RegistrationDate,103)as RegistrationDate ,FormFilledAt,CreationBy
from Table_Candidate_Info where Status='Completed'
order by CONVERT(VARCHAR(10),RegistrationDate,103) desc
Note: You don't need group by since you are not using any aggregated function
The reason why results are not ordered by RegistrationDate when you convert it to a varchar in Select clause is because Order By clause is logically processed after evaluation of Select clause.
Now in first query when you write
Select * from Table_Candidate_Info order by RegistrationDate desc
[Though writing * in select list is a very bad practice] format of RegistrationDate still remains date in Select clause which holds true for further logical processing phase of Order By clause. Hence 31.01.2019 comes first and 31.12.2018 later.
But when you convert it to varchar(10) to get a required format then actually Order By clause is ordering a Varchar and not Date. Hence 31/12/2018 comes first and 31/01/2019 comes after it.
To resolve the problem if you want to retain the formatting of datetime/date column in Select but Order By with Date value then simply cast the datetime column back to Date in Order by clause.
Pseudo code as:
select CONVERT(VARCHAR(10),RegistrationDate,103) as RegistrationDate from
Table_Candidate_Info
order by cast(RegistrationDate as Date) desc -- cast it back to date
Demo Link here: https://rextester.com/WMLQL78387

Athena greater than condition in date column

I have the following query that I am trying to run on Athena.
SELECT observation_date, COUNT(*) AS count
FROM db.table_name
WHERE observation_date > '2017-12-31'
GROUP BY observation_date
However it is producing this error:
SYNTAX_ERROR: line 3:24: '>' cannot be applied to date, varchar(10)
This seems odd to me. Is there an error in my query or is Athena not able to handle greater than operators on date columns?
Thanks!
You need to use a cast to format the date correctly before making this comparison. Try the following:
SELECT observation_date, COUNT(*) AS count
FROM db.table_name
WHERE observation_date > CAST('2017-12-31' AS DATE)
GROUP BY observation_date
Check it out in Fiddler: SQL Fidle
UPDATE 17/07/2019
In order to reflect comments
SELECT observation_date, COUNT(*) AS count
FROM db.table_name
WHERE observation_date > DATE('2017-12-31')
GROUP BY observation_date
You can also use the date function which is a convenient alias for CAST(x AS date):
SELECT *
FROM date_data
WHERE trading_date >= DATE('2018-07-06');
select * from my_schema.my_table_name where date_column = cast('2017-03-29' as DATE) limit 5
I just want to add my little words here, if you have date column with ISO-8601 format, for example: 2022-08-02T01:46:46.963120Z then you can use parse_datetime function.
In my case, the query looks like this:
SELECT * FROM internal_alb_logs
WHERE elb_status_code >= 500 AND parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') > parse_datetime('2022-08-01-23:00:00','yyyy-MM-dd-HH:mm:ss')
ORDER BY time DESC
See more other examples here: https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html#query-alb-logs-examples

Display a date that is the same as today in SQL Server [duplicate]

I have a table TEST with a DATETIME field, like this:
ID NAME DATE
1 TESTING 2014-03-19 20:05:20.000
What I need a query returning this row and every row with date 03/19/2014, no matter what the time is. I tried using
select * from test where date = '03/19/2014';
But it returns no rows. The only way to make it work that I found is to also provide the time portion of the date:
select * from test where date = '03/19/2014 20:03:02.000';
use range, or DateDiff function
select * from test
where date between '03/19/2014' and '03/19/2014 23:59:59'
or
select * from test
where datediff(day, date, '03/19/2014') = 0
Other options are:
If you have control over the database schema, and you don't need the
time data, take it out.
or, if you must keep it, add a computed column attribute that has the time portion of the date value stripped off...
Alter table Test
Add DateOnly As
DateAdd(day, datediff(day, 0, date), 0)
or, in more recent versions of SQL Server...
Alter table Test
Add DateOnly As
Cast(DateAdd(day, datediff(day, 0, date), 0) as Date)
then, you can write your query as simply:
select * from test
where DateOnly = '03/19/2014'
Simple answer;
select * from test where cast ([date] as date) = '03/19/2014';
I am using MySQL 5.6 and there is a DATE function to extract only the date part from date time. So the simple solution to the question is -
select * from test where DATE(date) = '2014-03-19';
http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html
This works for me for MS SQL server:
select * from test
where
year(date) = 2015
and month(date) = 10
and day(date)= 28 ;
select * from test
where date between '03/19/2014' and '03/19/2014 23:59:59'
This is a realy bad answer. For two reasons.
1.
What happens with times like 23.59.59.700 etc.
There are times larger than 23:59:59 and the next day.
2.
The behaviour depends on the datatype.
The query behaves differently for datetime/date/datetime2 types.
Testing with 23:59:59.999 makes it even worse because depending on the datetype you get different roundings.
select convert (varchar(40),convert(date , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime , '2014-03-19 23:59:59.999'))
select convert (varchar(40),convert(datetime2 , '2014-03-19 23:59:59.999'))
-- For date the value is 'chopped'.
-- For datetime the value is rounded up to the next date. (Nearest value).
-- For datetime2 the value is precise.
use this
select * from TableName where DateTimeField > date() and DateTimeField < date() + 1
Try this
select * from test where Convert(varchar, date,111)= '03/19/2014'
you can try this
select * from test where DATEADD(dd, 0, DATEDIFF(dd, 0, date)) = '03/19/2014';
There is a problem with dates and languages and the way to avoid it is asking for dates with this format YYYYMMDD.
This way below should be the fastest according to the link below. I checked in SQL Server 2012 and I agree with the link.
select * from test where date >= '20141903' AND date < DATEADD(DAY, 1, '20141903');
Bad habits to kick : mis-handling date / range queries
You can use this approach which truncates the time part:
select * from test
where convert(datetime,'03/19/2014',102) = DATEADD(dd, DATEDIFF(dd, 0, date), 0)
-- Reverse the date format
-- this false:
select * from test where date = '28/10/2015'
-- this true:
select * from test where date = '2015/10/28'
Simply use this in your WHERE clause.
The "SubmitDate" portion below is the column name, so insert your own.
This will return only the "Year" portion of the results, omitting the mins etc.
Where datepart(year, SubmitDate) = '2017'
select *, cast ([col1] as date) <name of the column> from test where date = 'mm/dd/yyyy'
"col1" is name of the column with date and time
<name of the column> here you can change name as desired
select *
from invoice
where TRUNC(created_date) <=TRUNC(to_date('04-MAR-18 15:00:00','dd-mon-yy hh24:mi:ss'));
Test this query.
SELECT *,DATE(chat_reg_date) AS is_date,TIME(chat_reg_time) AS is_time FROM chat WHERE chat_inbox_key='$chat_key'
ORDER BY is_date DESC, is_time DESC
select * from invoice where TRANS_DATE_D>= to_date ('20170831115959','YYYYMMDDHH24MISS')
and TRANS_DATE_D<= to_date ('20171031115959','YYYYMMDDHH24MISS');
SELECT * FROM test where DATEPART(year,[TIMESTAMP]) = '2018' and DATEPART(day,[TIMESTAMP]) = '16' and DATEPART(month,[TIMESTAMP]) = '11'
use trunc(column).
select * from test t where trunc(t.date) = TO_DATE('2018/06/08', 'YYYY/MM/DD')

How can I order by a date in string format properly?

I have a table with the following fields in an SQL Server 2005 database:
id, integer
value, string
create_date, datetime
New data is constantly being inserted into this table (tens of thousands of records per day) so I use the following query to compare how much data has been inserted on different days.
SELECT CONVERT(varchar(10), create_date, 101) as 'Date', COUNT(*) as 'Record Count',
FROM the_table
GROUP BY CONVERT(varchar(10), create_date, 101)
ORDER BY 'Date' desc
This query returns data looking like this:
12/20/2012 | 48155
12/19/2012 | 87561
12/18/2012 | 71467
However, when running this query today, I noticed the sorting did not work as expected with multiple years worth of data in the database. Instead of the data for this year being at the very top of the result set, it ended up at the bottom (records omitted for clarity)
06/29/2012 | 9987
01/04/2013 | 15768
01/03/2013 | 77586
01/02/2013 | 23566
I understand why this is happening, as my formatted date is simply a string, and sql server can't possibly be expected to sort it as anything but a string. But I would like the ordering to be accurate. How can I achieve this? (the most recent day always appearing first)
Thanks to Oded's suggestion I changed my order by clause and this seems to give me what I want:
SELECT CONVERT(varchar(10), create_date, 101) as 'Date', COUNT(*) as 'Record Count',
FROM the_table
GROUP BY CONVERT(varchar(10), create_date, 101)
ORDER BY MIN(create_date) desc
You can include the date as a date data type in the GROUP BY and then use it in the ORDER BY
SELECT top 100 CONVERT(varchar, create_date, 101) as 'Date', COUNT(*) as 'Record Count'
FROM constituent
GROUP BY CONVERT(varchar, create_date, 101), CONVERT(date, create_date)
ORDER BY CONVERT(date, create_date)
You could truncate the date to 12:00am instead of casting to a string:
SELECT dateadd(dd, datediff(dd, 0, create_date), 0) as 'Date'
, COUNT(*) as 'Record Count',
FROM the_table
GROUP BY dateadd(dd, datediff(dd, 0, create_date), 0)
ORDER BY dateadd(dd, datediff(dd, 0, create_date), 0) desc
You can probably substr then order by year desc, then month asc and date asc.
Does the data have to have only the two columns you specified? If not, you could select the date truncated to midnight (as user1948904 suggested) as well as the formatted-date field, and then order by the date field. Then you can ignore the date field in whatever uses the data.
Edited to correct errors in the original query, and to add the formatted-date field to the GROUP BY, which is required.
SELECT DATEADD(DAY, 0, DATEDIFF(DAY, 0, create_date)) AS raw_date,
CONVERT(VARCHAR(10), create_date, 101) AS 'Date',
COUNT(*) AS 'Record Count',
FROM the_table
GROUP BY DATEADD(DAY, 0, DATEDIFF(DAY, 0, create_date)),
CONVERT(VARCHAR(10), create_date, 101)
ORDER BY raw_date DESC
I find the other answers unsuitable for my situation because I don't want an additional redundant date column or have to use a GROUP BY if I'm not really aggregating any information in the query (granted the OP's question includes count(*) - my case is identical except I'm not aggregating).
This solution uses a DATEADD() that doesn't really do anything to force SQL Server to treat it as an actual date and return the right order.
SELECT [Date] = CONVERT(varchar(10), t.[create_date], 101)
[Thing] = t.[other_column] -- that I don't want to aggregate
FROM [db].[dbo].[mytable] t
ORDER BY DATEADD(dd, 0, t.[create_date]) DESC
I don't know anything about sql-server but I'll try to help. You should replace this column with one that is a Date type. I'm sure sql-server will know how to sort that correctly.
If that isn't an option for you, maybe in sql-server you can order by a function that converts the string to a date type.
But it already looks like you're using a date type here. I think you should just expand your query to include the date column in the select as the date type and sort by that column instead of the converted column.

How can I group by date time column without taking time into consideration

I have a bunch of product orders and I'm trying to group by the date and sum the quantity for that date. How can I group by the month/day/year without taking the time part into consideration?
3/8/2010 7:42:00 should be grouped with 3/8/2010 4:15:00
Cast/Convert the values to a Date type for your group by.
GROUP BY CAST(myDateTime AS DATE)
GROUP BY DATEADD(day, DATEDIFF(day, 0, MyDateTimeColumn), 0)
Or in SQL Server 2008 onwards you could simply cast to Date as #Oded suggested:
GROUP BY CAST(orderDate AS DATE)
In pre Sql 2008 By taking out the date part:
GROUP BY CONVERT(CHAR(8),DateTimeColumn,10)
CAST datetime field to date
select CAST(datetime_field as DATE), count(*) as count from table group by CAST(datetime_field as DATE);
GROUP BY DATE(date_time_column)
Here's an example that I used when I needed to count the number of records for a particular date without the time portion:
select count(convert(CHAR(10), dtcreatedate, 103) ),convert(char(10), dtcreatedate, 103)
FROM dbo.tbltobecounted
GROUP BY CONVERT(CHAR(10),dtcreatedate,103)
ORDER BY CONVERT(CHAR(10),dtcreatedate,103)
Here is the example works fine in oracle
select to_char(columnname, 'DD/MON/yyyy'), count(*) from table_name group by to_char(createddate, 'DD/MON/yyyy');
Well, for me it was pretty much straight, I used cast with groupby:
Example:
Select cast(created_at as date), count(1) from dbname.tablename GROUP BY cast(created_at as date)
Note: I am using this on MSSQL 2016.
I believe you need to group by , in that day of the month of the year .
so why not using TRUNK_DATE functions .
The way it works is described below :
Group By DATE_TRUNC('day' , 'occurred_at_time')