这是合约。我有一张数据表。我需要根据某些字段填充行出现的字段。我可能有一排,我可能有10排。我需要填充这个数字。我一直在使用rownumber()来确定数字是多少。但是更新表格一直存在问题。我已经尝试了连接,使用tablename as,然后选择,然后更新。没有任何效果。
此代码:
update Rptdata
SET c98 = (SELECT R from
(select rs1.c1, rs1.c5,rs1.c3,
row_number() over(partition by rs1.c1,0, rs1.c5,rs1.c3 order by rs1.c1,rs1.c5,rs1.c3 desc) as R
from Rptdata rs1
where rs1.c1 = c1
and rs1.c5 = c5
and rs1.c3 = c3
-- and rs1.c6 = c6
-- and rs1.c7 = c7
-- and rs1.c8 = c8
-- and rs1.c9 = c9
and rs1.program_name = 'INTERNAL'
AND rs1.program_id=030911
AND (rs1.c6 IS NULL
or rs1.c8 IS NULL
or rs1.c9 IS NULL)
and rs1.c28 IS NULL
)
)
WHERE program_name = 'INTERNAL'
AND program_id=030911
AND (c6 IS NULL
or c8 IS NULL
or c9 IS NULL)
and c28 IS NULL
生成错误ORA-01427:单行子查询返回多行。我认为这就是我想要的。我取消评论 - 而rs1.c6 = c6 它告诉我我更新了187行(这是正确的)。我提交然后在那187行上运行一个选择,而c98中没有任何内容。
答案 0 :(得分:4)
问题在于您需要将整个子查询作为一个单独的集处理,以便row_number
为您提供所需的结果,但您还需要将该集合减少为单个记录为了更新每一行。虽然使用update
可以实现这一点,但在这种情况下使用merge
会更直接(假设您使用的是10g):
MERGE INTO rptdata rp
USING (SELECT ROW_NUMBER() OVER (PARTITION BY rs1.c1, 0, rs1.c5, rs1.c3
ORDER BY rs1.c1, rs1.c5, rs1.c3 DESC) AS r
FROM rptdata rs1
WHERE rs1.program_name = 'INTERNAL'
AND rs1.program_id = 030911
AND (rs1.c6 IS NULL OR rs1.c8 IS NULL OR rs1.c9 IS NULL)
AND rs1.c28 IS NULL) rs
ON (rs.c1 = rp.c1 AND rs.c5 = rp.c5 AND rs.c3 = rp.c3)
WHEN MATCHED THEN
UPDATE SET
c98 = rs.r
WHERE program_name = 'INTERNAL'
AND program_id = 030911
AND (c6 IS NULL OR c8 IS NULL OR c9 IS NULL)
AND c28 IS NULL
顺便提一下,您提供的查询并不遥远。如上所述,您需要使用row_number
获取整个集合,然后筛选每个要更新的行所需的单个记录。为此,您需要将连接条件移动到外部查询:
UPDATE rptdata
SET c98 =
(SELECT r
FROM (SELECT rs1.c1,
rs1.c5,
rs1.c3,
ROW_NUMBER() OVER (PARTITION BY rs1.c1, 0, rs1.c5, rs1.c3
ORDER BY rs1.c1, rs1.c5, rs1.c3 DESC)
AS r
FROM rptdata rs1
WHERE rs1.program_name = 'INTERNAL'
AND rs1.program_id = 030911
AND (rs1.c6 IS NULL OR rs1.c8 IS NULL OR rs1.c9 IS NULL)
AND rs1.c28 IS NULL)
WHERE rs1.c1 = c1 AND rs1.c5 = c5 AND rs1.c3 = c3)
WHERE program_name = 'INTERNAL'
AND program_id = 030911
AND (c6 IS NULL OR c8 IS NULL OR c9 IS NULL)
AND c28 IS NULL