我需要将varchar2数据类型列与数字格式的日期值排序为AppBaseTheme
到YYMM
值范围为
MMYY
长度为4个字符的值表示1900年到1999年之间的年份 少于4个字符表示年份从2000年及以上开始。
我尝试使用LPAD(fieldname,4,' 0')将值返回为
3
6
9
12
103
.
.
9909
9912
如何根据从1900年开始按升序排列的年份值来排序列。 任何人都可以请我提供解决方案......
答案 0 :(得分:1)
您需要首先区分现有的四位数值,因此您知道它们是20世纪的日期,然后再填补其余的数据。
然后将其转换为日期并摆弄格式以获得所需的排序顺序:
select to_char( expanded_dt, 'MMYYYY') as switched_dt
from (
select to_date(
case when length(dt) = 4 then '19'||dt
else '20'||lpad(dt,4,'0') end
, 'YYYYMM' )
as expanded_dt
from your_table
)
order by 1 asc
/
答案 1 :(得分:0)
首先,将 DATE 值存储为 VARCHAR2 且仅使用部分元素是一种糟糕的设计。从长远来看,你应该先修改你的设计。
作为解决方法,如果年份值在1950-2049
范围内,您可以使用 RR
格式两位数年。< / p>
TO_DATE(LPAD(date_column, 4,'0'), 'RRMM')
LPAD
会添加所需的前导零。
例如,
SQL> alter session set nls_date_format='MM/DD/YYYY';
Session altered.
SQL> WITH dates AS(
2 SELECT '3' dt FROM dual UNION ALL
3 SELECT '6' dt FROM dual UNION ALL
4 SELECT '9' dt FROM dual UNION ALL
5 SELECT '12' dt FROM dual UNION ALL
6 SELECT '103' dt FROM dual UNION ALL
7 SELECT '9909' dt FROM dual UNION ALL
8 SELECT '9912' dt FROM dual
9 )
10 SELECT dt,
11 TO_DATE(LPAD(dt, 4,'0'), 'RRMM') date_val
12 FROM dates
13 ORDER BY date_val;
DT DATE_VAL
---- ----------
9909 09/01/1999
9912 12/01/1999
3 03/01/2000
6 06/01/2000
9 09/01/2000
12 12/01/2000
103 03/01/2001
7 rows selected.
SQL>
因此,上面的查询为您提供了所需的输出,日期值现在按升序排序。
答案 2 :(得分:0)
您可以根据值的长度添加世纪标记:
select value,
case when length(value) = 4 then '19' else '20' end || lpad(value, 4, '0') as dt
from t
order by case when length(value) = 4 then '19' else '20' end || lpad(value, 4, '0');
VALUE DT
---------- ------
9909 199909
9912 199912
6 200006
9 200009
12 200012
103 200103
或者使用相同的东西并转换为日期,默认为每月的第一天:
select value, to_date(case when length(value) = 4 then '19' else '20' end
|| lpad(value, 4, '0'), 'YYYYMM') as dt
from t
order by to_date(case when length(value) = 4 then '19' else '20' end
|| lpad(value, 4, '0'), 'YYYYMM');
VALUE DT
---------- ----------
9909 1999-09-01
9912 1999-12-01
6 2000-06-01
9 2000-09-01
12 2000-12-01
103 2001-03-01
如果您只查看1950-2049 Y2K安全范围内的日期,您可以跳过世纪部分并使用RR日期模型,但是因为这可能会导致您以后出现问题&# 39;在使用长度来支撑世纪方面确实有任何优势:
select value, to_date(lpad(value, 4, '0'), 'RRMM') as dt
from t
order by to_date(lpad(value, 4, '0'), 'RRMM');
VALUE DT
---------- ----------
9909 1999-09-01
9912 1999-12-01
6 2000-06-01
9 2000-09-01
12 2000-12-01
103 2001-03-01