Sql 如何以字符串格式按日期正确订购?
我在SQL Server 2005数据库中有一个包含以下字段的表:Sql 如何以字符串格式按日期正确订购?,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我在SQL Server 2005数据库中有一个包含以下字段的表: id,整数 值,字符串 create_date,datetime 新数据不断地插入到这个表中(每天有上万条记录),所以我使用下面的查询来比较在不同的日子插入了多少数据 SELECT CONVERT(varchar(10), create_date, 101) as 'Date', COUNT(*) as 'Record Count', FROM the_table GROUP BY CONVERT(varchar(10),
id,整数
值,字符串
create_date,datetime
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
此查询返回如下所示的数据:
12/20/2012 | 48155
12/19/2012 | 87561
12/18/2012 | 71467
然而,当今天运行这个查询时,我注意到对于数据库中多年的数据,排序并没有像预期的那样起作用。今年的数据不是在结果集的顶端,而是在底部(为了清楚起见,省略了记录)
我理解发生这种情况的原因,因为我的格式化日期只是一个字符串,sql server不可能将其作为字符串进行排序。但我希望订单是准确的。我怎样才能做到这一点?(最近的一天总是第一个出现)我对sql server一无所知,但我会尽力帮助你。应将此列替换为日期类型的列。我相信sql server将知道如何正确排序 如果这不是您的选项,那么在sql server中,您可以通过将字符串转换为日期类型的函数进行排序
但看起来你已经在使用日期类型了。我认为您应该扩展查询,将select中的date列作为日期类型,并按该列而不是转换的列进行排序。感谢Oded的建议,我更改了order by子句,这似乎给了我想要的:
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
您可以将日期作为日期数据类型包含在“分组依据”中,然后在“排序依据”
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)
您可以将日期截断为12:00am,而不是转换为字符串:
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
您可能可以按年份描述、月份asc和日期asc排序。数据是否只包含您指定的两列?如果没有,您可以选择截断到午夜的日期(如建议的)以及格式化的日期字段,然后按日期字段排序。然后,您可以忽略使用数据的任何内容中的日期字段 编辑以更正原始查询中的错误,并将格式化的日期字段添加到
分组依据中,这是必需的
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
我发现其他答案不适合我的情况,因为如果我没有真正聚合查询中的任何信息,我不想再增加一个冗余的日期列,或者必须使用分组依据
(假设OP的问题包括计数(*)
-我的案例相同,但我没有聚合)
此解决方案使用了一个DATEADD()
,它实际上不会强制SQL Server将其视为实际日期并返回正确的顺序
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
不要。按实际日期排序,然后格式化。@Oded EDIT:没关系,我想我已经解决了。这很简单…您可以使用DATEPART
进行分组。您使用的是什么版本的SQL Server?因为对于SQL Server 2008+有一个DATE
数据类型。而且,在使用Converter时,您应该始终使用varchar的长度。在指定varchar
时,您应该始终使用长度,因此请使用varchar(32)
或其他内容。此列是日期时间,必须用于其他目的,因此,我不能实际更改表结构,也不能将其包含在select中,因为我是按日期时间的子集(仅日期部分)分组的。不过,我还是设法弄明白了-无论如何,谢谢。再次,请养成习惯,明确使用VARCHAR
和长度(如VARCHAR(10)
),不要依靠VARCHAR
总是自己猜测长度,您最终会得到惊喜SQL Server 2005上没有DATE
数据类型。请在varchar上使用显式长度
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