【问题标题】:Sort the list of employees by day of the week starting Monday in Oracle在 Oracle 中从星期一开始按星期几对员工列表进行排序
【发布时间】:2019-06-23 00:40:00
【问题描述】:

我正在使用 oracle 中的默认 scott 模式编写一般 sql 查询。 使用 emp 表。

在这里,我想根据应该从星期一开始的日期显示和排序结果。即星期一雇用的人应该在顶部,然后是星期二,依此类推直到星期日。

我把这个查询写成:

select * from emp order by to_char(hiredate,'DAY') ; 

但上面的查询按工作日的字母顺序显示结果,即(周五雇用的人排在首位,然后是周一、周六等)

请帮忙。

【问题讨论】:

  • 也许select * from emp order by to_char(hiredate,'D') ;
  • @DavidAldridge - 这可能适用于英国,但不适用于美国。 'D' 选项取决于本地设置(nls_region 等),不能作为TO_CHAR 的输入给出 - 在美国,星期日 = 1,星期一 = 2。
  • @mathguy 啊,当然!

标签: sql database oracle date sql-order-by


【解决方案1】:

试试:

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 documentation 说:

NLS_TERRITORY 指定区域的名称,其日期和星期编号要遵循其惯例。

默认情况下,此会话参数是从服务器的默认值初始化的。因此,要以可移植的方式使用 D 说明符,您需要首先更改会话设置。

但请注意,此参数还控制其他会话参数(日期格式、小数分隔符、货币符号...)的 默认值:修改它可能会影响在同一会话中运行的其他查询令人惊讶的方式。

考虑这个演示

今天是 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., 更改为 , :这是因为默认值 @987654343 @ 被隐式更改(当NLS_TERRITORY 被更改时)并且客户端没有为该参数设置显式值。棘手。

Demo on DB Fiddle

注意:与NLS_DATE_LANGUAGE 参数不同,Oracle 不允许将NLS_TERRITORY 作为第三个参数传递给TO_CHAR(我想这是因为它控制了其他参数的默认值)。

【讨论】:

    猜你喜欢
    • 2019-02-26
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多