按星期几排序 - 解码返回null

时间:2016-03-12 17:47:45

标签: sql sorting oracle11g

我需要从EMPLOYEES表中获取一些数据,并根据hire_date创建名称为week的新列。然后必须按星期几(从星期一到星期日)对结果进行排序,这就是我的问题所在。

我决定使用解码功能,但好像我做错了。

这是我的查询

SELECT FIRST_NAME, LAST_NAME, HIRE_DATE, TO_CHAR(HIRE_DATE, 'DAY', 'NLS_DATE_LANGUAGE=ENGLISH') AS DAY_OF_WEEK FROM EMPLOYEES ORDER BY DECODE(DAY_OF_WEEK,'MONDAY',1,'TUESDAY',2,'WEDNESDAY',3,'THURSDAY',4,'FRIDAY',5,'SATURDAY',6,'SUNDAY',7)

除了排序外,一切运作良好。周三正处于开始阶段,其余部分是随机排列的。

我稍微更改了一下查询,所以我可以看到这个函数是如何工作的。

SELECT FIRST_NAME, LAST_NAME, HIRE_DATE, TO_CHAR(HIRE_DATE, 'DAY', 'NLS_DATE_LANGUAGE=ENGLISH') AS DAY_OF_WEEK, DECODE(TO_CHAR(HIRE_DATE, 'D', 'NLS_DATE_LANGUAGE=ENGLISH'), 'MONDAY',1, 'TUESDAY',2,  'WEDNESDAY',3,  'THURSDAY',4,  'FRIDAY',5,  'SATURDAY',6,  'SUNDAY',7) AS DAY2 FROM EMPLOYEES ORDER BY DECODE(DAY_OF_WEEK, 'MONDAY',1, 'TUESDAY',2,  'WEDNESDAY',3,  'THURSDAY',4,  'FRIDAY',5,  'SATURDAY',6,  'SUNDAY',7)

像这样的东西在星期三的第DAY2栏第3号和其他一切的(null)栏中返回。

这就解释了为什么排序不起作用,但我仍然不知道为什么它不起作用以及查询中的错误在哪里:)

2 个答案:

答案 0 :(得分:1)

问题是这一天用空格填充。 "星期三"匹配,因为它是最长的工作日名称。如果你这样做,你可以看到这个:

nl_groups

如果您可以使用星期几缩写:

SELECT '|' || TO_CHAR(HIRE_DATE, 'DAY', 'NLS_DATE_LANGUAGE=ENGLISH') || '|'
FROM EMPLOYEES ;

我更喜欢ANSI标准SELECT FIRST_NAME, LAST_NAME, HIRE_DATE, TO_CHAR(HIRE_DATE, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AS DAY_OF_WEEK FROM EMPLOYEES ORDER BY DECODE(DAY_OF_WEEK, 'MON', 1, 'TUE', 2, 'WED', 3, 'THU', 4, 'FRI', 5, 'SAT', 6, 'SUN', 7); 而非CASE,但两者都适用于此背景。

答案 1 :(得分:1)

这使得逻辑更难理解但满足了需要。

https://docs.oracle.com/cloud/latest/db112/SQLRF/functions255.htm#SQLRF52058 ..

'IW'与ISO周的第一天(周一)相同的一周

with EMPLOYEES as (
SELECT 'Paul1' First_Name, 'Revere' Last_name, To_date('1-MAR-2016') Hire_Date FROM DUAL UNION ALL
SELECT 'Paul2', 'Revere', to_date('2-MAR-2016') FROM DUAL UNION ALL
SELECT 'Paul3', 'Revere', to_date('3-MAR-2016') FROM DUAL UNION ALL
SELECT 'Paul4', 'Revere', to_date('4-MAR-2016') FROM DUAL UNION ALL
SELECT 'Paul5', 'Revere', to_date('5-MAR-2016') FROM DUAL UNION ALL
SELECT 'Paul6', 'Revere', to_date('6-MAR-2016') FROM DUAL UNION ALL
SELECT 'Paul7', 'Revere', to_date('7-MAR-2016') FROM DUAL)

SELECT FIRST_NAME, LAST_NAME, HIRE_DATE
, TO_CHAR(HIRE_DATE, 'DAY', 'NLS_DATE_LANGUAGE=ENGLISH') AS DAY_OF_WEEK
FROM EMPLOYEES 
order by TRUNC (Hire_Date) - TRUNC (Hire_Date, 'IW')