在 Oracle SQL 中使用 CTE(ORA-00923:在预期的地方找不到 FROM 关键字)

Posted

技术标签:

【中文标题】在 Oracle SQL 中使用 CTE(ORA-00923:在预期的地方找不到 FROM 关键字)【英文标题】:Using CTE in Oracle SQL (ORA-00923: FROM keyword not found where expected) 【发布时间】:2021-06-05 09:22:42 【问题描述】:

问题:从下表包含订购日期和项目的列表中,编写一个查询以返回每个日期订购频率最高的项目。在平局的情况下返回多个项目。

Oracle SQL 中的问题输入

create table items(dates varchar2(200), item VARCHAR2(200));

insert into items values ('01-01-20', 'apple');
insert into items values ('01-01-20', 'apple');
insert into items values ('01-01-20', 'pear');
insert into items values ('01-01-20', 'pear');
insert into items values ('01-02-20', 'pear');
insert into items values ('01-02-20', 'pear');
insert into items values ('01-02-20', 'pear');
insert into items values ('01-02-20', 'orange');

这是我要执行的代码。但是,我得到一个错误

ORA-00923:在预期的地方找不到 FROM 关键字

有人可以帮忙吗?

select dates, item
from 
(
SELECT *, rank() OVER (PARTITION by dates ORDER BY item_count DESC) AS date_rank
FROM 
(
SELECT dates, item, count(*) AS item_count
FROM items
GROUP BY 1, 2
ORDER BY 1))
where date_rank=1;

【问题讨论】:

我在您的问题中没有看到任何 CTE。 【参考方案1】:

我已将您的子查询中的* 替换为dates, items,并将group by 子句从group by 1,2 更改为group by dates, items。它正在工作。

但我建议使用在我看来更具可读性且易于更改的查询#2。

 create table items(dates varchar2(200), item VARCHAR2(200));

 insert into items values ('01-01-20', 'apple');

 insert into items values ('01-01-20', 'apple');

 insert into items values ('01-01-20', 'pear');

 insert into items values ('01-01-20', 'pear');

 insert into items values ('01-02-20', 'pear');

 insert into items values ('01-02-20', 'pear');

 insert into items values ('01-02-20', 'pear');

 insert into items values ('01-02-20', 'orange');

查询#1:

select dates, item
     from 
     (
     SELECT dates,item, rank() OVER (PARTITION by dates ORDER BY item_count DESC) AS date_rank
     FROM 
     (
     SELECT dates, item, count(*) AS item_count
     FROM items
     GROUP BY dates, item
     ORDER BY dates) ) 
     where date_rank=1;

输出:

DATES ITEM
01-01-20 apple
01-01-20 pear
01-02-20 pear

查询#2:

 with cte (dates,item,date_rank) as
 (  
    SELECT dates, item,rank() OVER (PARTITION by dates ORDER BY count(*) DESC)  AS date_rank
    FROM items
    GROUP BY dates, item
    ORDER BY dates
 )
 select  dates,item from cte 
 where date_rank=1;

输出:

DATES ITEM
01-01-20 apple
01-01-20 pear
01-02-20 pear

dbhere

【讨论】:

嗨,Kazi,这是完美的。你能解释一下吗?我的错误是什么? @Ashima 我已经用解释修改了我的答案。 谢谢。你能告诉我为什么它可以替换 * 和 1 和 2 吗?任何具体原因。抱歉,我正在尝试从头开始学习 SQL,所以这个技巧可能非常有用。 您使用的是哪个版本的 oracle dbms?你也可以使用 items.* 这很好。列号可以在 order by 子句中使用,但不能在 group by 子句中使用。 列别名也是如此:您可以在 order by 子句中使用它们,但不能在 group by 子句中使用它们。您可以查看 oracle 查询的执行顺序。不用客气。最良好的祝愿。你的努力值得点赞。

以上是关于在 Oracle SQL 中使用 CTE(ORA-00923:在预期的地方找不到 FROM 关键字)的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 中的变量声明、CTE 和 While 循环

MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

SQL 中with的用法

SQL中使用WITH 语句的查询

在 Oracle SQL Developer 中使用 tnsnames.ora

在 oracle SQL 中使用 insrt 函数遇到“ORA-00907:缺少右括号”