Использование функции to_char внутри оператора case с Oracle APEX

Я работал над Oracle APEX, написав запрос, который дает список предстоящих дней рождения студентов в 2016 году и упорядочивает их в хронологическом порядке. Это сработало, и я использовал следующий код:

SELECT first_name, last_name, to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy') AS birthday
FROM students
WHERE date_of_birth IS NOT NULL
ORDER BY birthday

Это дало правильный результат и начало показывать имена с хронологически упорядоченными днями рождения в 2016 году.

Однако теперь я хотел получить еще один столбец, показывающий, в какой день ученики празднуют свой день рождения в классе. Таким образом, для учащихся, день рождения которых приходится на будний день, это будет тот же день, а для учащихся, у которых день рождения приходится на выходные, это будет понедельник, используя оператор case, чтобы изменить «субботу» или «воскресенье» на «понедельник».

Я уже сделал запрос, который показывает, в какой день отмечается день рождения студента, который дает правильный вывод, например, «пятница» или «среда», код:

SELECT first_name, last_name, to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy') AS birthday, to_char(to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy'), 'day') AS celebrationday
FROM students
WHERE date_of_birth IS NOT NULL
ORDER BY birthday

Я уже сделал несколько простых тестов с оператором case, например добавил что-то, когда имя «Джон», например:

SELECT student_number, first_name,
(CASE first_name
WHEN 'John' THEN 'Check'
END) addition
FROM Students

Что привело к правильному выводу; для всех имен, кроме «Джон», столбец дополнение будет нулевым, а для тех, у кого есть имя, в столбце дополнение будет указано «Проверить».

Теперь начинается основная проблема, когда я пытаюсь воспроизвести это, чтобы проверить, приходится ли праздникдень на выходные, я либо получаю следующую ошибку: 'ORA-00904 'праздникдень': неверный идентификатор ' для этого фрагмента кода:

SELECT first_name, last_name, to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy') AS birthday, to_char(to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy'), 'day') AS celebrationday,
(CASE celebrationday
WHEN 'saturday' THEN 'monday'
WHEN 'sunday' THEN 'monday'
END) addition
FROM students
WHERE date_of_birth IS NOT NULL
ORDER BY birthday

(Небольшой комментарий, я знаю, что кейс должен также содержать другие дни недели, но сначала я заинтересован в том, чтобы получить правильный вывод из выходных дней)

Или для следующего фрагмента кода я просто не получаю никаких результатов в столбце дополнение, только нулевые значения.

SELECT first_name, last_name, to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy') AS birthday,
CASE to_char(to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy'), 'day)
WHEN 'saturday' THEN 'monday'
WHEN 'sunday' THEN 'monday'
END) addition
FROM Students
WHERE date_of_birth IS NOT NULL
ORDER BY date_of_birth
  • Что мне нужно сделать, чтобы заставить работать заявление о случае, чтобы я мог изменить праздничный день? Я надеюсь, что предоставленные примеры кода достаточно ясны для работы и дадут вам представление о том, что работает, а что нет.

person KRAD    schedule 16.10.2015    source источник


Ответы (3)


Ах... вы используете to_char для возврата дня. Вам нужно будет учитывать конечные пробелы в вашем запросе. Значение по существу имеет вид char(9).

Я думаю, что если вы обрежете результат и добавите условие ELSE для учета других дней, все будет хорошо.

    CASE trim(to_char(to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy'), 'day'))
    WHEN 'saturday' THEN 'monday'
    WHEN 'sunday' THEN 'monday'
    else trim(to_char(to_date(concat(to_char(date_of_birth, 'dd-mm'), '-2016'), 'dd-mm-yyyy'), 'day'))
    END addition
person knuckles    schedule 16.10.2015
comment
Спасибо за вашу помощь, я попробовал, и это сработало, для нескольких студентов, у которых день празднования приходится на выходные дни, теперь отображается понедельник. Не могли бы вы подробнее объяснить, в чем именно заключалась проблема с конечными пробелами? - person KRAD; 17.10.2015
comment
Рад, что это сработало. В соответствии со спецификацией использования элемента формата «ДЕНЬ» возвращаемое значение будет дополнено пробелами для отображения ширины самого широкого имени дня на языке даты, используемом для этого элемента. docs.oracle.com/cd/B28359_01/server.111/ b28286/ - person knuckles; 20.10.2015

Чтобы сослаться на празднование дня в операторе case, вам нужно обернуть его во внутренний запрос. select case celebrationday = . . . from ( select . . . as celebrationday . . . ). Внутренний запрос для его определения и внешний для ответа на него.

person Paul Kienitz    schedule 17.10.2015

Вы можете вообще не работать с названиями дней:

SELECT 1 + TRUNC (birthday_dt) - TRUNC (birthday_dt, 'IW') day_of_week
, birthday_dt 
  + CASE 1 + TRUNC (birthday_dt) - TRUNC (birthday_dt, 'IW')
      WHEN 6 THEN 2 
      WHEN 7 THEN 1
      ELSE 0 
    END corrected_dt
, to_char(
  birthday_dt 
  + CASE 1 + TRUNC (birthday_dt) - TRUNC (birthday_dt, 'IW')
      WHEN 6 THEN 2 
      WHEN 7 THEN 1
      ELSE 0 
    END
  , 'fmDay') corrected_day
from 
(
select to_date('19/10/2015','DD/MM/YYYY') birthday_dt from dual --monday
union all
select to_date('20/10/2015','DD/MM/YYYY') birthday_dt from dual
union all
select to_date('21/10/2015','DD/MM/YYYY') birthday_dt from dual
union all
select to_date('22/10/2015','DD/MM/YYYY') birthday_dt from dual
union all
select to_date('23/10/2015','DD/MM/YYYY') birthday_dt from dual
union all
select to_date('24/10/2015','DD/MM/YYYY') birthday_dt from dual
union all
select to_date('25/10/2015','DD/MM/YYYY') birthday_dt from dual --sunday
);

Запустите его в инструменте Oracle LiveSQL

DAY_OF_WEEK CORRECTED_DT CORRECTED_DAY
1           19-OCT-15    Monday
2           20-OCT-15    Tuesday
3           21-OCT-15    Wednesday
4           22-OCT-15    Thursday
5           23-OCT-15    Friday
6           26-OCT-15    Monday
7           26-OCT-15    Monday

День недели (1 + TRUNC (dt) - TRUNC (dt, 'IW')) взят из: https://community.oracle.com/thread/2207756

person Tom    schedule 19.10.2015