Sql 如何以字符串格式按日期正确订购?

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),

我在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), 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