按星期一到星期日的星期几排序

deb*_*e4u 20 sql oracle sql-order-by

如果我写

select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";
Run Code Online (Sandbox Code Playgroud)

然后根据Day对结果进行排序; 从星期五,然后是周一和上周三,就像按字符排序一样.

但是我想在一周之前对它进行排序; 从周一到周日.

Ben*_*Ben 11

你按照你的顺序得到它,因为你用字符串排序(这不会起作用,因为你没有选择任何东西).

您可以按照用于以数字形式创建星期几的格式模型进行排序D,但由于星期日为1,我建议您使用mod()此工作.

即假设表

create table a ( b date );

insert into a
 select sysdate - level
  from dual
connect by level <= 7;
Run Code Online (Sandbox Code Playgroud)

这可行:

select mod(to_char(b, 'D') + 5, 7) as dd, to_char(b, 'DAY')
  from a
 order by mod(to_char(b, 'D') + 5, 7)
Run Code Online (Sandbox Code Playgroud)

这是一个演示的SQL小提琴.

在您的情况下,您的查询将变为:

select ename, to_char(hiredate,'fmDay') as "Day" 
  from my_table
 order by mod(to_char(hiredate, 'D') + 5, 7)
Run Code Online (Sandbox Code Playgroud)

  • D格式掩码返回的值受会话的NLS_TERRITORY设置影响。运行此程序(在英国领土内)(http://www.sqlfiddle.com/#!4/59e8f/913),您将首先获得星期二 (3认同)

And*_*ter 9

看看的其他格式TO_CHAR。不用'fmDay'而是使用'D',它会给您星期几从1到7。然后您可以轻松地对它进行排序。

以下是日期格式的列表:http : //docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

  • `NLS_TERRITORY` 设置影响哪一天是 1;对美国来说,这是星期天,对大多数其他国家来说,这是星期一。所以你不能依赖这个 (2认同)

2ma*_*raf 8

我只是遇到了相同的要求-按星期几来查询查询结果,但不能从星期日开始。我在Oracle中使用以下查询从星期一开始。(对其进行修改以在一周的任何一天开始订购,例如,将“ MONDAY”更改为“ TUESDAY”。)

SELECT ename, to_char(hiredate, 'fmDAY') AS "Day" 
FROM emp
ORDER BY (next_day(hiredate, 'MONDAY') - hiredate) DESC
Run Code Online (Sandbox Code Playgroud)

要么:

SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (hiredate - next_day(hiredate, 'MONDAY'))
Run Code Online (Sandbox Code Playgroud)


Chr*_*xon 7

将星期几映射到值1-7 的D格式掩码to_char

但!

此输出取决于客户端的NLS_TERRITORY设置。美国认为星期日是第一天。而世界上大多数其他国家都认为星期一是开始:

alter session set nls_territory = AMERICA;

with dts as (
  select date'2018-01-01' + level - 1 dt 
  from   dual
  connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
       to_char ( dt, 'd' ) day_number
from   dts
order  by day_number;

DAY_NAME    DAY_NUMBER   
Sunday       1             
Monday       2             
Tuesday      3             
Wednesday    4             
Thursday     5             
Friday       6             
Saturday     7  

alter session set nls_territory = "UNITED KINGDOM";

with dts as (
  select date'2018-01-01' + level - 1 dt 
  from   dual
  connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
       to_char ( dt, 'd' ) day_number
from   dts
order  by day_number;

DAY_NAME    DAY_NUMBER   
Monday       1             
Tuesday      2             
Wednesday    3             
Thursday     4             
Friday       5             
Saturday     6             
Sunday       7
Run Code Online (Sandbox Code Playgroud)

遗憾的是,与许多其他NLS参数不同,您不能将NLS_TERRITORY作为以下参数的第三个参数to_char

with dts as (
  select date'2018-01-01' dt 
  from   dual
)
select to_char ( dt, 'Day', 'NLS_DATE_LANGUAGE = SPANISH' ) day_name
from   dts;

DAY_NAME    
Lunes  

with dts as (
  select date'2018-01-01' dt 
  from   dual
)
select to_char ( dt, 'Day', 'NLS_TERRITORY = AMERICA' ) day_name
from   dts;

ORA-12702: invalid NLS parameter string used in SQL function
Run Code Online (Sandbox Code Playgroud)

因此,任何依赖于D排序的解决方案都是一个错误!

为避免这种情况,请从日期中减去最近的星期一(如果今天是星期一,则最近的星期一=今天)。您可以使用IW格式掩码来执行此操作。返回ISO周的开始。始终是星期一:

with dts as (
  select date'2018-01-01' + level - 1 dt 
  from   dual
  connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
       ( dt - trunc ( dt, 'iw' ) ) day_number
from   dts
order  by day_number;

DAY_NAME    DAY_NUMBER   
Monday                   0 
Tuesday                  1 
Wednesday                2 
Thursday                 3 
Friday                   4 
Saturday                 5 
Sunday                   6 
Run Code Online (Sandbox Code Playgroud)

对于周日至周六的排序,请在日期之前添加一个,然后再找到ISO周的开始时间:

with dts as (
  select date'2018-01-01' + level - 1 dt 
  from   dual
  connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
       ( dt - trunc ( dt + 1, 'iw' ) ) day_number
from   dts
order  by day_number;

DAY_NAME    DAY_NUMBER   
Sunday                  -1 
Monday                   0 
Tuesday                  1 
Wednesday                2 
Thursday                 3 
Friday                   4 
Saturday                 5 
Run Code Online (Sandbox Code Playgroud)


Rea*_*mae 6

当您可以添加与天数相对应的数字1-7的另一列然后按此列排序时,为什么会变得复杂...

  • 根据国家/地区的不同,一周中的 1 天可能是周一/周日 (3认同)

小智 6

SELECT
     *
FROM
     classes
ORDER BY 
     CASE
          WHEN Day = 'Sunday' THEN 1
          WHEN Day = 'Monday' THEN 2
          WHEN Day = 'Tuesday' THEN 3
          WHEN Day = 'Wednesday' THEN 4
          WHEN Day = 'Thursday' THEN 5
          WHEN Day = 'Friday' THEN 6
          WHEN Day = 'Saturday' THEN 7
     END ASC
Run Code Online (Sandbox Code Playgroud)

假设该用户有一个名为classes的表,则该用户具有class_id(主键),类名Day。


Luk*_*zda 6

如果您希望星期一始终被视为一周的第一天,则可以使用:

-- Not affected by NLS_TERRITORY
-- ALTER SESSION SET NLS_TERRITORY="AMERICA";  -- Sunday is first day of week
-- ALTER SESSION SET NLS_TERRITORY="GERMANY";  -- Monday is first day of week

SELECT *
FROM tab
ORDER BY 1+TRUNC(dt)-TRUNC(dt,'IW');
Run Code Online (Sandbox Code Playgroud)

db <> fiddle演示


boo*_*oon 5

这很简单。

SELECT last_name, hire_date,TO_CHAR(hire_date, 'DAY') DAY
FROM employees
ORDER BY TO_CHAR(hire_date - 1, 'd');
Run Code Online (Sandbox Code Playgroud)

TO_CHAR(hire_date - 1, 'd') 将“星期一”放入名为“星期日”的框中。


use*_*457 5

正如它所说,它有一个功能

SELECT *
FROM table
ORDER BY WEEKDAY(table.date);
Run Code Online (Sandbox Code Playgroud)

  • 不,没有: SELECT weekday(sysdate) FROM dual; ORA-00904: "WEEKDAY": 无效标识符 (4认同)