我正在使用oracle中的默认scott模式编写常规sql查询。 使用emp表。
在这里,我想根据星期几开始显示和排序结果。也就是说,周一雇用的人员应该排在首位,然后是周二,以此类推,直到周日。
我将此查询写为:
select * from emp order by to_char(hiredate,'DAY') ;
但是上面的查询以星期几的字母顺序显示结果,即(周五的受雇人员排在顶部,然后是周一,周六,依此类推)
Kinldy帮助。
答案 0 :(得分:2)
尝试:
select * from emp order by trunc(hire_date) - trunc(hire_date, 'IW')
这可以通过计算自一周初(星期一开始)以来经过的天数来工作。它将在星期一返回0
,在星期日返回6
。
为什么有效
trunc(hire_date) - trunc(hire_date, 'IW')
所有内容都在Oracle date format specifiers的文档中:
IW
:一年中的日历周(1-52或1-53),由ISO 8601标准定义。 一个日历周从星期一开始。
由于此说明符依赖于ISO标准,因此不受其调用所在会话的NLS设置的影响(有关避免的复杂性,请进一步参见)。这使该方法具有完全的可移植性(并且仍然有效,因为它只包含两次转换)。
TO_CHAR
方法的问题
Oracle提供了TO_CHAR()
function,可与D
格式说明符一起使用以返回星期几。如记录所示,此元素取决于会话的NLS范围。
NLS_TERRITORY
指定要在日期和星期编号中遵循的惯例的地区名称。
默认情况下,此会话参数是从服务器的默认值初始化的。因此,要以可移植的方式使用D
说明符,您首先需要更改会话设置。
但是请注意,此参数还会控制其他会话参数(日期格式,小数点分隔符,货币符号等)的 default :修改它可能会影响在同一会话中运行的其他查询令人惊讶的方式。
考虑此演示
今天是1月28日,星期三,因此是星期三。我们将在不指定任何NLS参数的情况下创建一个新会话,然后:
SELECT parameter, value from v$nls_parameters WHERE parameter = 'NLS_TERRITORY';
PARAMETER | VALUE
:------------ | :------
NLS_TERRITORY | AMERICA
SELECT TO_CHAR(sysdate, 'd') FROM DUAL;
| TO_CHAR(SYSDATE,'D') |
| :------------------- |
| 4 |
在使用服务器的默认地区(美国)时,我们得到的结果是错误的:Oracle认为在美国,星期几从星期日开始。
让我们将参数更改为星期一从几周开始的地区:
ALTER SESSION SET NLS_TERRITORY = 'FRANCE';
SELECT TO_CHAR(sysdate, 'd') FROM DUAL;
| TO_CHAR(SYSDATE,'D') |
| :------------------- |
| 3 |
现在我们正在获得想要的结果...但是,您应该意识到,与此同时,Oracle将会话参数NLS_NUMERIC_CHARACTERS
从.,
更改为,
:这是因为NLS_NUMERIC_CHARACTERS
的默认值被隐式更改(更改NLS_TERRITORY
时),并且客户端没有为该参数集显式地设置任何值。棘手的。
NB:与NLS_DATE_LANGUAGE
参数不同,Oracle不允许将NLS_TERRITORY
作为第三个参数传递给TO_CHAR
(我想这是因为它控制其他参数的默认值)。 / p>