2016-03-12 3 views
0

Мне нужно получить некоторые данные из таблицы EMPLOYEES и создать новый столбец с именем недели, основанный на hire_date. Результаты затем должны быть отсортированы по дням недели (с понедельника по воскресенье), и вот где моя проблема.Сортировка по дням недели - декодирование возвращает null

Я решил использовать функцию декодирования, но похоже, что я делаю что-то неправильно.

Вот мой запрос

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) для всего остального.

Это объясняет, почему сортировка не работает, но я до сих пор не знаю, почему это не работает, и где ошибка в запросе :)

ответ

1

Проблема заключается в том, что день дополняется пробелами. Матч «среда», потому что это самое длинное название дня недели. Вы можете увидеть это, если вы:

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

Если вы можете жить с днем ​​недели сокращений:

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); 

Я предпочитаю ANSI стандарт CASE вместо DECODE(), но и работу в этом контексте.

+0

Вы правы! Я не понимал, что после имен есть пробелы. Что касается аббревиатур, я думаю, что они достаточно хороши, поэтому я могу использовать их вместо полных имен :) Большое вам спасибо! – xyz124

+0

Мне всегда нравится знать, почему ... объясняют это пробелы. – xQbert

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') 
+0

Поскольку вы не возвращаете номер дня, нет необходимости в '1 +' :-) – dnoeth

+0

true, что .... Удалено. – xQbert

Смежные вопросы