我有一个适用于我当前MySQL数据库的MySQL查询。我被迫转移到oracle,所以我试图将所有存储过程/程序移植到使用Oracle SQL语法。我在一个特定的查询上遇到了很多麻烦。这是MySQL查询。它使用子查询更新表。
update table1 alf
set nextcontractid =
(
select
contractid from table1copy alf2
where
alf2.assetid = alf.AssetID
and
alf2.lasttradedate > alf.LastTradeDate
order by lasttradedate asc limit 1
)
where complete = 0
在oracle中,我无法使用limit命令,所以我一直在寻找解决方法。这是我的oracle查询。 (这不起作用。)
update table1 alf
set nextcontractid =
(select contractid from
(
SELECT contractid, rownum as row_number
FROM table1copy alf2
WHERE alf2.assetid = alf.assetid
AND alf2.lasttradedate > alf.lasttradedate
ORDER BY lasttradedate ASC
)
where row_number = 1)
where alf.complete = 0
我收到以下错误:
Error at Command Line:8 Column:29
Error report:
SQL Error: ORA-00904: "ALF"."LASTTRADEDATE": invalid identifier
00904. 00000 - "%s: invalid identifier"
第8行是:
AND alf2.lasttradedate > alf.lasttradedate
删除update语句并在子查询中放入一些虚拟值会产生子查询的正确结果:
(select contractid from
(
SELECT contractid, rownum as row_number
FROM asset_list_futures_copy alf2
WHERE alf2.assetid = 'GOLD'
AND alf2.lasttradedate > '20110101'
ORDER BY lasttradedate ASC
)
where row_number = 1)
查看错误,看起来对alf的第二个引用不起作用。知道如何更改我的查询以便它在oracle中工作吗?
答案 0 :(得分:2)
似乎解析器不喜欢它,尽管事实上它是正确的。可能这两个有条不紊和有序的条款让他以某种方式致盲。我再现了。
您可以使用分析功能:
update table1 alf
set nextcontractid =
(SELECT min(contractid) keep (dense_rank first order by lasttradedate asc)
FROM table1copy alf2
WHERE alf2.assetid = alf.assetid
AND alf2.lasttradedate > alf.lasttradedate
)
where alf.complete = 0
答案 1 :(得分:0)
如果您想获得更多结果,可以使用WHERE rownum = 1
或rownum BETWEEN x AND y
。