如何以指定格式对包含DATE的列进行排序?

时间:2015-08-26 12:29:19

标签: sql oracle sorting date

我有一个SQL SELECT语句,如下所示:

SELECT NAME, ID, TO_CHAR(AUDIT_TIMESTAMP, 'DD-MON-YYYY') AS AUDIT_TIMESTAMP,
TO_CHAR(HIST_TIMESTAMP, 'DD-MON-YYYY') AS HIST_TIMESTAMP
FROM 
MY_TABLE
WHERE 1=1
AND NAME = 'PK_01_123'
AND REVIEWED_FLAG IS NULL
ORDER BY AUDIT_TIMESTAMP DESC
;

MY_TABLE.AUDIT_TIMESTAMP的值格式为:28-FEB-09 12.29.23.740174000 AM

输出表只留下28-FEB-09部分。

现在 - 对我来说最重要的是按降序对结果中的AUDIT_TIMESTAMP进行排序。有没有办法正确有效地做到这一点?我可以像YYYY-MON-DD一样格式化输出,但仍然 - 它将按年份排序,然后 - 按月计算。有没有办法按日期排序,所以如果我的日期如下:

12-JAN-2014
10-FEB-2015
01-MAR-2013

排序的结果将是:

10-FEB-2015
12-JAN-2014
01-MAR-2013

如果这有任何帮助,我正在使用ORACLE数据库...

提前致谢!

2 个答案:

答案 0 :(得分:4)

问题是您要将列重命名为与原始列相同的名称。因此,ORDER BY使用重新格式化的版本。

因此,只需在ORDER BY中使用合格的列名:

SELECT NAME, ID, TO_CHAR(AUDIT_TIMESTAMP, 'DD-MON-YYYY') AS AUDIT_TIMESTAMP,
       TO_CHAR(HIST_TIMESTAMP, 'DD-MON-YYYY') AS HIST_TIMESTAMP
FROM MY_TABLE
WHERE 1=1 AND NAME = 'PK_01_123' AND REVIEWED_FLAG IS NULL
ORDER BY MY_TABLE.AUDIT_TIMESTAMP DESC;

答案 1 :(得分:2)

您的ORDER BY条款没有问题。但是您的别名与order by子句中使用的列名称匹配的事实,实际排序基于 TO_CHAR 值,该值是 STRING 而不再是<强> DATE 即可。

  

永远记住,对于DATE, TO_CHAR 仅显示日期   以所需格式将数据类型从日期更改为字符串,用于   任何日期算术,将数据类型保留为DATE。

例如,我正在对标准hiredate表的EMP列进行排序:

SQL> SELECT TO_CHAR(hiredate, 'DD-MON-YYYY') hiredate FROM emp ORDER BY hiredate DESC;

HIREDATE
-----------
28-SEP-1981
23-JAN-1982
22-FEB-1981
20-FEB-1981
17-NOV-1981
17-DEC-1980
12-JAN-1983
09-JUN-1981
09-DEC-1982
08-SEP-1981
03-DEC-1981
03-DEC-1981
02-APR-1981
01-MAY-1981

14 rows selected.

以上输出发生了什么?排序不正确,因为它将日期排序为字符串,因此它根据字符串的 ASCII 值进行排序。

SQL> SELECT TO_CHAR(hiredate, 'DD-MON-YYYY') new_date FROM emp ORDER BY hiredate DESC;

NEW_DATE
-----------
12-JAN-1983
09-DEC-1982
23-JAN-1982
03-DEC-1981
03-DEC-1981
17-NOV-1981
28-SEP-1981
08-SEP-1981
09-JUN-1981
01-MAY-1981
02-APR-1981
22-FEB-1981
20-FEB-1981
17-DEC-1980

14 rows selected.

SQL>

以上输出已正确排序,因为现在它根据 DATE 进行排序。

简单的解决方案是更改别名,并让 ORDER BY 保持原样:

SELECT NAME,
  ID,
  TO_CHAR(AUDIT_TIMESTAMP, 'DD-MON-YYYY') AS AUD_TIMESTAMP,
  TO_CHAR(HIST_TIMESTAMP, 'DD-MON-YYYY')  AS HIST_TIMESTAMP
FROM MY_TABLE
WHERE 1            =1
AND NAME           = 'PK_01_123'
AND REVIEWED_FLAG IS NULL
ORDER BY AUDIT_TIMESTAMP DESC ;