应用程序开发人员要求我修改查询并根据created_date列按年命令一个游览DESC,因为创建的日期是DateTime格式我尝试创建一个视图,将日期转换为显示游览年份的列,它看起来像这样:
视图:
CREATE VIEW vw.v_tour_year AS
SELECT to_char(created_date,'YYYY') "tour_year", tour_id, tour_name
FROM vw.tour
以下是需要更新的Package正文中的QUERY:
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订购它?
该查询不包含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
语法。几十年来,人们不鼓励使用逗号进行隐式连接。
两件事情。
因此有一个问题
SELECT to_char(created_date,'YYYY') "tour_year"
您已双引用视图列的别名。在Oracle中,对象名称都是大写的,无论定义它的表达式是什么情况,除非你用双引号括起它们。你基本上有2个选项。
ORDER BY vt."tour_year"
。我肯定会推荐第一个选项。
另一个重要的一点是,您应该习惯使用下面的ANSI JOIN语法而不是旧的a,b
语法进行连接。
tu JOIN vw.v_tour_year vt
ON ( tu.tour_id = vt.tour_id )