2013-01-04 115 views
4

我有以下字段的表中的SQL Server 2005數據庫:如何以字符串格式的日期正確地訂購?

  • id, integer
  • value, string
  • 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 

然而,今天運行此查詢時,我注意到,與多年值得數據庫中的數據的預期排序沒有工作。相反,今年是在結果集的最頂端的數據,它結束了在底部(省略清晰的記錄)

06/29/2012 | 9987 
01/04/2013 | 15768 
01/03/2013 | 77586 
01/02/2013 | 23566 

我明白爲什麼發生這種情況,因爲我格式化日期簡單地說就是一個字符串,並且不能期望sql server將它排序爲除字符串之外的任何內容。但我希望訂購是準確的。我怎樣才能做到這一點? (最近一天總是先出現)

+4

不要。按實際日期排序,然後格式化。 – Oded

+0

@Oded編輯:沒關係,我想我解決了它。這很簡單... – Mansfield

+0

你可以使用'DATEPART'進行分組。 – Oded

回答

10

由於俄德的建議,我一條一條地改變了我的訂單,這似乎給我什麼,我想:

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 
+5

再次強調,明確使用長度爲'VARCHAR'(如'VARCHAR(10)')的習慣,不要依靠'VARCHAR'來總是自己猜測長度,否則會得到一個驚喜最終 – Lamak

+0

@Lamak完成。謝謝! – Mansfield

0

我對sql-server一無所知,但我會盡力幫忙。您應該將此列替換爲日期類型的列。我敢肯定sql-server會知道如何正確排序。

如果這不是您的選擇,也許在sql-server中,您可以通過函數將字符串轉換爲日期類型。


但它已經看起來像你在這裏使用日期類型。我認爲你應該擴大查詢的範圍,將date列包含在select中作爲日期類型,並按該列進行排序,而不是轉換後的列。

+0

此列是日期時間,必須用於其他目的,所以我實際上不能更改表結構。 – Mansfield

+0

啊,好的。我編輯了我的評論 –

+0

我無法將它包含在select中,因爲我正在按日期時間的子集(僅日期部分)進行分組。我確實設法弄清楚了 - 無論如何。 – Mansfield

2

可以包含日期作爲GROUP BY日期數據類型,然後在使用它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) 
+2

在SQL Server 2005上沒有'DATE'數據類型。並且請在varchars上使用顯式長度 – Lamak

0

你可以截斷日至上午12:00,而不是強制轉換爲字符串:

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 
+0

SELECT子句不會保留所需的格式。 – bobs

0

你可以用substr然後按年降序排列,然後按月排序asc和日期asc。

0

數據是否有只有您指定的兩列?如果不是,則可以選擇截至午夜的日期(如user1948904建議的)以及格式化日期字段,然後按日期字段排序。然後,您可以忽略數據使用的任何日期字段。

編輯爲更正原始查詢中的錯誤,並將格式化日期字段添加到需要的GROUP BY

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 
0

,我覺得我的情況不適合其他的答案,因爲我不希望額外的冗餘日期欄或必須使用GROUP BY,如果我真的不聚集在查詢的任何信息(授予OP的問題包括count(*) - 我的情況是相同的,除非我不彙總)。

該解決方案使用了一個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 
相關問題