Sql 带联接的内部查询中的ORDERBY子句
Products表有两个条目-伪(标志='Y')和实际(标志='N') 如果没有伪产品,则需要获取实际产品 上述查询导致编译错误。Sql 带联接的内部查询中的ORDERBY子句,sql,plsql,oracle11g,Sql,Plsql,Oracle11g,Products表有两个条目-伪(标志='Y')和实际(标志='N') 如果没有伪产品,则需要获取实际产品 上述查询导致编译错误。 内部查询可能返回多条记录,但我只需要第一条记录(即“Y”记录。如果找不到“Y”记录,则需要“N”记录)。有点过火,但应该可以: create table items(item_pk integer, pgid integer, prod_id integer, PRIMARY KEY(item_pk)); create table products(prod_id
内部查询可能返回多条记录,但我只需要第一条记录(即“Y”记录。如果找不到“Y”记录,则需要“N”记录)。有点过火,但应该可以:
create table items(item_pk integer, pgid integer, prod_id integer, PRIMARY KEY(item_pk));
create table products(prod_id integer, version integer, pgid integer, flag char(1), PRIMARY KEY(prod_id));
insert into items(item_pk, pgid) values (1, 21);
insert into items(item_pk, pgid) values(2, 31);
insert into products(prod_id, version, pgid, flag) values (11, 101, 21, 'Y');
insert into products(prod_id, version, pgid, flag) values (22, 101, 21, 'N');
insert into products(prod_id, version, pgid, flag) values(33, 101, 31, 'N');
declare
prod_version NUMBER := :1 ;
begin
update items i set i.prod_id = (
select p.prod_id from products p where
p.version = prod_version and p.pgid = i.pgid and rownum =1
order by p.flag desc
) where i.xyz is null
commit; end;
您需要在更新查询中进行另一次选择。我想应该是这样的
select prod_id
from (
select p.prod_id, ROW_NUMBER() OVER (ORDER BY p.flag DESC) as rn
from products p
where p.version = prod_version and p.pgid = i.pgid
)
where rn=1
我没有可用的ide来检查我的语法。我在一个文本编辑器中做这件事,所以可能会有bug 我总是尽量避免在查询中使用任何类型的rownum,因此这可能需要使用“N”值的子查询
update items i set i.prod_id = (
select prod.id from (
select p.prod_id,rownum rn from products p where
p.version = prod_version and p.pgid = i.pgid
order by p.flag desc) x
where x.rn=1
) where i.xyz is null
但是,您可以始终使用plsql并执行类似的操作
declare
prod_version NUMBER := :1 ;
begin
update items i set i.prod_id = (select p.prod_id
from products p
where p.version = prod_version
and p.pgid = i.pgid
and (p.flag = 'Y'
or (p.flag = 'N' and 0 = (select count(*)
from products p2
where p2.version = prod_version
and p2.pgid = i.pgid
and p2.flag = 'Y')
)
)
)
where i.xyz is null
commit;
end;
正如我上面所说的,我可以随意处理这个问题,所以请仔细检查语法。@YasinOkumus:内部查询可能会返回两条记录。如果存在,我需要“Y”记录,否则需要“N”记录。我晚了些时候才知道这一点,所以我删除了我的评论。对不起。我正在写一个答案,我希望这次我答对了,你能得到答案。:)“and rownum=1”是否试图只获取一条记录?我尝试了此操作,但无法识别内部查询中的“I”。我现在无法尝试,但这很奇怪。也许你应该考虑修改更新查询,因为这里是用这两个表(项目和产品)的连接来写的:在阅读之后,你可能想把关键字“区分”添加到那个查询中。但我不知道他桌上有什么。
declare
temp_prod_id number;
prod_version NUMBER := :1 ;
begin
for v_rec in (select id, pgid from items where xyz is null) loop
begin
select prod_id into temp_prod_id from products p
where p.version = prod_version
and p.pgid = v_rec.pgid
and p.flag = 'Y';
exception
when no_data_found then
select prod_id into temp_prod_id from products p
where p.version = prod_version
and p.pgid = v_rec.pgid
and p.flag = 'N';
-- this assumes there's always an 'N' record if not wrap this select with exception handling.
end;
update items i set i.prod_id = temp_prod_id
where items.id = v_rec.id;
commit;
end loop;
end;