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)
8条答案
按热度按时间egmofgnx1#
Thanks to Oded's suggestion I changed my order by clause and this seems to give me what I want:
nimxete22#
You can include the date as a date data type in the
GROUP BY
and then use it in theORDER BY
jbose2ul3#
You could truncate the date to 12:00am instead of casting to a string:
q8l4jmvw4#
You can probably substr then order by year desc, then month asc and date asc.
hsgswve45#
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.gt0wga4j6#
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 includescount(*)
- 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.luaexgnf7#
This is old I know, but I ran into this problem today with a script for work. We are running a report with a DATETIME column where we only actually ever stored the DATE, not the time, so the time shows up as 12:00AM over and over on the report which is both meaningless and redundant, so I wanted to format the value to not display the time, and I ran into this same problem because we are ordering by that same DATETIME column. Simply using FORMAT or CONVERT threw an error, and Left to truncate the value did something weird I really didn't expect - it made the DATETIME display the month as a text abbreviation - Jan 23, 2023, Feb 03, 2023, etc... Peculiar!
Anyway, I found the easiest solution was to use FORMAT on my DATETIME column instead of CONVERT, because while that formats the date so that displays the way I need it to, it seems that SQL still treats the column as a DATETIME this way and thus it sorts correctly.
How ever it is worth noting one must use FORMAT on both instances of the column - in the SELECT statement and the ORDER BY clause! Otherwise there is an error thrown if only one the SELECT statement is formatted.
Here's the an example of the query in my stored procedure with the other conditions needed for running the report removed:
select distinct property_id as 'Property ID', format(last_visit, 'yyyy-MM-dd') as 'Last Visit', street_num + ' ' + address as 'Address', city as 'City', county as 'County', state as 'State', zip_code as 'Zipcode' from property order by format(last_visit, 'yyyy-MM-dd') asc
uelo1irk8#
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.