如果我写
select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";
然后它根据 Day 对结果进行排序;从周五开始,然后是周一和上周三,就像按字符排序一样。
但我想按星期几排序;从周一到周日。
如果我写
select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";
然后它根据 Day 对结果进行排序;从周五开始,然后是周一和上周三,就像按字符排序一样。
但我想按星期几排序;从周一到周日。
你按你的顺序得到它,因为你是按字符串排序的(这不起作用,因为你没有从任何东西中选择)。
您可以按用于以数字形式创建星期几的格式模型D
订购,但由于星期日是 1,我建议使用mod()
它来完成这项工作。
即假设桌子
create table a ( b date );
insert into a
select sysdate - level
from dual
connect by level <= 7;
这会起作用:
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)
这是一个要演示的SQL Fiddle 。
在您的情况下,您的查询将变为:
select ename, to_char(hiredate,'fmDay') as "Day"
from my_table
order by mod(to_char(hiredate, 'D') + 5, 7)
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
假设用户有一个名为 classes 的表,该表中用户有 class_id(主键)、类名、Day。
当您可以添加另一列对应天数的 1-7 列然后按此列排序时,为什么要复杂化...
看看其他格式的TO_CHAR
. 而不是 'fmDay' 使用 'D' 它将为您提供从 1 到 7 的星期几。然后您可以轻松地对其进行排序。
以下是日期格式列表: http: //docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm
我刚刚遇到了同样的要求——按星期几排序查询结果,但不是从星期日开始。我在 Oracle 中使用以下查询从星期一开始。(修改它以在一周中的任何一天开始订购,例如,将“MONDAY”更改为“TUESDAY”。)
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (next_day(hiredate, 'MONDAY') - hiredate) DESC
或者:
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (hiredate - next_day(hiredate, 'MONDAY'))
将星期几映射到值 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
遗憾的是,与许多其他 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
所以任何依赖于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
对于周日-周六排序,在找到 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
如果您希望星期一始终被视为一周的第一天,您可以使用:
-- 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');
这很简单。
SELECT last_name, hire_date,TO_CHAR(hire_date, 'DAY') DAY
FROM employees
ORDER BY TO_CHAR(hire_date - 1, 'd');
TO_CHAR(hire_date - 1, 'd')
将“星期一”放入名为“星期日”的框中。
正如它所说,它有一个功能:
SELECT *
FROM table
ORDER BY WEEKDAY(table.date);
发布答案可能会迟到,但从星期一开始按星期几排序似乎很简单。
select hiredate,dayname(hiredate) from emp order by (dayofweek(hiredate)+5)%7;
回答为什么要加 5 ?
因为,在数字中,星期日的值为 1,星期一的值为 2……而星期六的值为 7
因此,从星期一开始,2 + 5 = 7 和 mod(%) 和 7 将为我们提供新值。
您可以更改此数字以从一周中的任何其他日期开始。
我通过给你一个从 1 而不是 0 开始的结果来改进 Ben 的答案。查询将是这样的:
select
mod(to_char(b, 'D')+ 5, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 5, 7);
另一方面,如果你希望你的一周从星期日开始,那么你应该使用这个查询:
select
mod(to_char(b, 'D')+ 6, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 6, 7)
希望这可以帮助 :)
这应该在 sql 中解决问题:
ORDER BY
CASE DATENAME(dw,<<enter your date variable here>>)
WHEN 'Monday' THEN 1
WHEN 'Tuesday' THEN 2
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 4
WHEN 'Friday' THEN 5
WHEN 'Saturday' THEN 6
WHEN 'Sunday' Then 7
END ASC;
当然,如果您想要不同的顺序,您只需在之后切换值。
至少对于 Postgres,要让星期一始终是第 1 天,请使用TO_CHAR(b, 'ID')
返回 ISO 8601 一周中的一天 - 星期一 (1) 到星期日 (7)。
这是国际标准组织 (ISO) 的一周中的一天,因此在“ID”中的 D 前面是 I。
我有一些简单的想法希望你喜欢。我不知道您使用的是哪个 sql,所以请更正语法错误。
select ename, to_char(hiredate,'fmDay') as "Day" from ABC_TABLE
JOIN (VALUES (1,'Monday'),(2,'Tuesday'),(3,'Wednesday'),(4,'Thursday'),(5,'Friday'),(6,'Saturday'),(7,'Sunday')) weekdays(seq,[Days]) on
ABC_TABLE.to_char(hiredate,'fmDay') = weekdays.[Days]
order by weekdays.seq;
我你想在一周结束后下周开始,然后找到一个月的季度并按顺序添加。
仅用于查找 Quarter in(MSSQL):select DatePart(QUARTER, cast(cast(mydate as char(8)) as date))
with s as (select trunc(sysdate) + level dt from dual connect by level <= 7)
select to_char(dt, 'fmDay', 'nls_date_language=English') d
from s
order by dt - trunc(dt, 'iw');
D
------------------------------------
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
7 rows selected.
我认为这为时已晚,但如果其他人需要,我会将其留在这里。
您可以按星期几订购,但这取决于您的会话区域。
为了显示领土,您可以简单地执行以下查询:
SELECT * FROM V$NLS_PARAMETERS WHERE parameter = 'NLS_TERRITORY';
NLS_TERRITORY
指定区域的名称,该区域的日期和星期编号要遵循其约定。
回到前面的查询,如果你有AMERICA
as 值,那么 Monday 的值为 2。
要从周一到周日订购您的结果,您至少有 2 条道路:
hire_date
:SELECT * FROM employees ORDER BY TO_CHAR(hire_date - 1, 'd');
FRANCE
:ALTER SESSION SET NLS_TERRITORY = 'FRANCE';
SELECT * FROM employees ORDER BY TO_CHAR(hire_date, 'd');
这是我的解决方案。
select ename, to_char(hiredate,'fmDay') "Day"
from employees
order by DECODE(to_number(to_char(hiredate ,'D'))-1,
0, 7,
to_number(to_char(hiredate ,'D'))-1);
基本上使用 to_char 函数中的 'D' 格式将日期转换为数字。
to_number(to_char(hire_date ,'D')
但这会导致星期日为 1,星期一为 2,依此类推,所以我减去 1 使星期一为 1。
(to_number(to_char(hire_date ,'D') - 1
然后我使用 DECODE 函数基本上说如果 0,则 7,否则为原始数字。这只会使星期日变成 7 而不是 0,其他一切都在适当的位置(星期一是 1,星期二是 2……依此类推)。
DECODE(to_number(to_char(hire_date ,'D'))-1,
0, 7,
to_number(to_char(hire_date ,'D'))-1);