我需要为以下逻辑编写Oracle Query代码,并且感谢任何帮助。
我有一个包含8列的表,其中需要考虑3列用于特定的业务逻辑。
表数据(3列)
A B C
071699 01 I
071699 01W
071699 02W
071699 01W I
071699 02W
更多行。
数据量因具体情况而异,这意味着每列A-B组合可能有一行或多行,通常不在这些行中 列C填充至少1个组合。
此表具有超过100K的不同A值。
逻辑我需要实现:
A B C
071699 01 I
071699 01W
071699 02W
查询后的数据
A B C
071699 01 I
071699 01W I
071699 02W I
我有一个SQL服务器查询在一个查询中执行此逻辑但在Oracle中无法运行,我收到错误,"单行查询返回多行"
SQL Server查询
update c
set c.colC = u.colC
from data_table u
join data_table c on u.colA = c.colA and u.colB <> c.colB
and u.colB = (select MIN(colB) from data_table
where colA = u.colA and colC is not null)
and u.colC is not null and c.colC is null
任何帮助都可以写出类似的oracle版本。
答案 0 :(得分:0)
Oracle不允许在更新查询中加入,除非您有一个唯一的列,该列保证1-1映射在您的情况下绝对不适用。所以你可以在这里做的最好的是一个嵌套的子查询。它不是很漂亮,但它会起作用。我无法将您需要实现的逻辑与SQL Server更新语句中的逻辑完全匹配,因此我接着使用了该语句。
UPDATE data_table u
SET u.COLC =(
SELECT c.ColC
FROM data_table c
WHERE c.ColA = u.ColA
and c.ColB =(
SELECT MIN( ColB )
FROM data_table
WHERE ColA = c.ColA
AND ColC IS NOT NULL
)
)
where u.ColC is null;
答案 1 :(得分:0)
我尝试了在单个查询中执行此任务的各种方法,但由于Oracle的限制而无法实现此任务,以下是解决方案适用于我:
我将查询分为两部分 - 一部分执行insert语句,另一部分执行update。
第一个查询:这里我将行插入另一个临时表,逻辑 - 每个colA获取不同的行 - ColC,其中colC是polulated。
使用在步骤1中创建的tmp表,通过colA上的join连接来更新主数据表。
如果有人有更好的解决方案,那么请发送您的回复,我一定会尝试。
答案 2 :(得分:0)
我在尝试各种方法(如拆分为两个tmp表,游标等)之后使用基于集合的编码解决了这个问题,下面是示例代码:
此查询比任何其他解决方案快3-5倍。
UPDATE data_table a SET C = (
WITH comp AS (
SELECT DISTINCT A, C FROM data_table a
WHERE B = (SELECT MIN(B) FROM data_table
WHERE A = a.A
AND C IS NOT NULL)
)
SELECT
CASE
when a.C IS NULL THEN c.C
when a.C IS NOT NULL THEN a.C
END
FROM comp c
WHERE a.A = c.A AND c.C IS NOT NULL
);