我在查询在Oracle 12.1而不是Oracle 11.2不能正常工作的情况下遇到了一个难题。经过一番挖掘,看来在Oracle 11.2中,如果子查询太深,则不能在最外面的查询中引用别名。
在下面的查询中,(1)和(2)都从各自的子查询中引用LT
,这些子查询是嵌套在UPDATE
内的两个或三个级别。显然,此限制已在12中删除,但在11.2中仍然存在,并且一直存在。
我不能使用WITH
子句,因为这是一个更新。还有其他解决方案可以使此查询在11.2中运行吗?
UPDATE TBL LT
SET LT.DW = 'W'
WHERE (LT.CID, LT.ID) IN (
SELECT
A.CID,
A.ID
FROM (
SELECT DISTINCT
CID,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY
(CASE
WHEN ((SELECT F.NET_INC
FROM BUDGET F
WHERE F.TRACE_ID = LT.TRACE_ID ) -- (1)
< (SELECT LOINC
FROM MAL
WHERE CODE = (SELECT F.SIZEC
FROM BUDGET F
WHERE F.TRACE_ID = LT.TRACE_ID))) -- (2)
THEN 1
ELSE 2
END),
OC_DT ,
CID) AS "RANK",
ID,
G_ID
FROM TBL
WHERE RN = 120) A
WHERE
A.RANK = 1
AND A.RN = 'B'
AND LT.STS = 'V'
);
答案 0 :(得分:1)
也许您可以尝试使用MERGE
。
我尝试(有点),但由于我没有您的桌子而无法对其进行测试。试试看,如有必要,请修复它(难怪您不必这样做)。
(顺便说一句,“大小”似乎是无效的列名,所以我给它加上了“ c”作为前缀。)
MERGE INTO tbl lt
USING (SELECT a.cid, a.id
FROM (
-- subquery where TRACE_ID isn't too deeply nested ...
SELECT DISTINCT
y.cid,
y.sts,
ROW_NUMBER ()
OVER (
PARTITION BY id
ORDER BY
CASE
WHEN ( (SELECT f.net_inc
FROM budget f
WHERE f.trace_id =
y.trace_id) <
(SELECT loinc
FROM mal
WHERE code =
(SELECT f.sizec
FROM budget f
WHERE f.trace_id =
y.trace_id)))
THEN
1
ELSE
2
END,
oc_dt,
cid)
AS rnk,
y.id,
y.g_id
FROM tbl y -- ... because you select from TBL in it
WHERE y.rn = 120) a
WHERE a.rnk = 1
AND a.rn = 'B'
AND a.sts = 'V') x
ON ( lt.cid = x.cid
AND lt.id = x.id)
WHEN MATCHED
THEN
UPDATE SET lt.dw = 'W';
或者,使用基于您的“ A”子查询的视图:
CREATE VIEW v_tbl
AS
SELECT DISTINCT
cid,
ROW_NUMBER ()
OVER (
PARTITION BY id
ORDER BY
(CASE
WHEN ( (SELECT f.net_inc
FROM budget f
WHERE f.trace_id = y.trace_id) -- (1)
<
(SELECT loinc
FROM mal
WHERE code = (SELECT f.csize
FROM budget f
WHERE f.trace_id = y.trace_id))) -- (2)
THEN
1
ELSE
2
END),
oc_dt,
cid)
AS rnk,
id,
g_id
FROM tbl y
WHERE rn = 120;
UPDATE tbl lt
SET lt.dw = 'W'
WHERE (lt.cid, lt.id) IN (SELECT v.cid, v.id
FROM v_tbl
WHERE v.rnk = 1
AND v.rn = 'B'
AND lt.sts = 'V');