Разработчик приложения попросил меня изменить запрос и заказать тур DESC по годам на основе столбца created_date, так как созданная дата находится в формате DateTime. Я попытался создать представление для преобразования даты в столбец, который показывает ГОД тура и его выглядит так:

ПОСМОТРЕТЬ:

CREATE VIEW vw.v_tour_year AS
SELECT to_char(created_date,'YYYY') "tour_year", tour_id, tour_name
FROM vw.tour

Вот ЗАПРОС из тела пакета, который нужно обновить:

SELECT tu.*
      FROM (
        SELECT t.tour_id, t.tour_name
        FROM vw.tour t
        WHERE NOT EXISTS (
          SELECT 'x'
          FROM vw.tour_locale l
          WHERE l.culture_id = 1
          AND l.tour_name IS NOT NULL
          AND t.tour_id = l.tour_id
        )     
        UNION
        SELECT l.tour_id, l.tour_name
        FROM vw.tour_locale l
        WHERE l.culture_id = 1
        AND l.tour_name IS NOT NULL
      ) tu, vw.v_tour_year vt
     WHERE tu.tour_id = vt.tour_id
     ORDER BY vt.tour_year desc, tu.tour_name asc;

Однако Oracle жалуется, что vt.tour_year - недопустимый идентификатор, который, как мне кажется, Oracle не позволяет мне. Это возможно? или я могу заказать только по created_date?

-1
Drew 22 Сен 2018 в 07:39

2 ответа

Лучший ответ

Запрос не включает столбцы из vt. Лично мне кажется странным, что сортировка выполняется не по select.

Вид кажется совершенно ненужным. Подумайте о том, чтобы написать запрос как:

SELECT tu.*,
       vt.created_date,
       to_char(vt.created_date, 'YYYY') as tour_year
FROM ((SELECT t.tour_id, t.tour_name
       FROM vw.tour t
       WHERE NOT EXISTS (SELECT 'x'
                         FROM vw.tour_locale l
                         WHERE l.culture_id = 1 AND
                               l.tour_name IS NOT NULL AND
                               t.tour_id = l.tour_id
                        )     
      ) UNION
      (SELECT l.tour_id, l.tour_name
       FROM vw.tour_locale l
       WHERE l.culture_id = 1 AND
             l.tour_name IS NOT NULL
      )
     ) tu JOIN
     vw.tour vt
     ON tu.tour_id = vt.tour_id
ORDER BY to_char(vt.created_date, 'YYYY') desc, tu.tour_name asc;

(Конечно, дополнительные столбцы в SELECT необязательны.)

Обратите внимание, что здесь также используется правильный стандартный явный JOIN синтаксис. Неявные соединения с использованием запятых не поощрялись десятилетиями.

1
Gordon Linoff 22 Сен 2018 в 11:31

Две вещи.

Из-за этого возникла проблема

SELECT to_char(created_date,'YYYY') "tour_year"

Вы дважды заключили в кавычки псевдоним для столбца представления. В Oracle имена объектов хранятся с заглавной буквы, независимо от регистра выражения, которое их определяет, если вы не заключили их в двойные кавычки. В основном у вас есть 2 варианта.

  1. Удалите кавычки из "tour_year" в определении представления и замените представление
  2. Если вам действительно нужен tour_year в нижнем регистре, вы можете ввести ORDER BY vt."tour_year".

Я определенно рекомендую первый вариант.

Другой важный момент заключается в том, что вы должны взять за правило использовать приведенный ниже синтаксис ANSI JOIN вместо старого синтаксиса a,b для объединений.

tu JOIN vw.v_tour_year vt
     ON ( tu.tour_id = vt.tour_id )
2
APC 22 Сен 2018 в 06:45