ted*_*ski 6 oracle subquery oracle11g
如何使用Oracle引用子查询之外的列?我特别需要在子查询的WHERE语句中使用它.
基本上我有这个:
SELECT Item.ItemNo, Item.Group
FROM Item
LEFT OUTER JOIN (SELECT Attribute.Group, COUNT(1) CT
FROM Attribute
WHERE Attribute.ItemNo=12345) A ON A.Group = Item.Group
WHERE Item.ItemNo=12345
Run Code Online (Sandbox Code Playgroud)
我想换WHERE Attribute.ItemNo=12345到WHERE Attribute.ItemNo=Item.ItemNo子查询,但我想不通这是可能的.我一直得到"ORA-00904:'Item'.'ItemNo':无效的标识符"
编辑:
好的,这就是我需要这种结构的原因:
我希望能够计算"错误"记录(项目缺少值)和"确定"记录(项目具有值).
我在小提琴中设置它的方式返回正确的数据.我想我可能最终会填写每个子查询中的值,因为这可能是最简单的方法.对不起,如果我的数据结构有点复杂.如果需要,我可以解释一下.
我的表是:
create table itemcountry(
itemno number,
country nchar(3),
imgroup varchar2(10),
imtariff varchar2(20),
exgroup varchar2(10),
extariff varchar2(20) );
create table itemattribute(
attributeid varchar2(10),
tariffgroup varchar2(10),
tariffno varchar2(10) );
create table icav(
itemno number,
attributeid varchar2(10),
value varchar2(10) );
Run Code Online (Sandbox Code Playgroud)
我到目前为止的查询是:
select itemno, country, imgroup, imtariff, im.error "imerror", im.ok "imok", exgroup, extariff, ex.error "exerror", ex.ok "exok"
from itemcountry
left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno
from itemattribute ia
left outer join icav on ia.attributeid=icav.attributeid
where (icav.itemno=12345 or icav.itemno is null)
group by tariffgroup, tariffno) im on im.tariffgroup=imgroup and imtariff=im.tariffno
left outer join (select sum(case when icav.itemno is null then 1 else 0 end) error, sum(case when icav.itemno is not null then 1 else 0 end) ok, tariffgroup, tariffno
from itemattribute ia
left outer join icav on ia.attributeid=icav.attributeid
where (icav.itemno=12345 or icav.itemno is null)
group by tariffgroup, tariffno) ex on ex.tariffgroup=exgroup and extariff=ex.tariffno
where itemno=12345;
Run Code Online (Sandbox Code Playgroud)
它也是在一个SQL小提琴中设置的.
您可以在子查询中执行此操作,但不能在联接中执行此操作。就你的情况而言,我认为没有必要。您可以将其放入连接条件中。
select i.itemno, i.group
from item i
left outer join ( select group, itemno
from attribute b
group by group itemno ) a
on a.group = i.group
and i.itemno = a.itemno
where i.itemno = 12345
Run Code Online (Sandbox Code Playgroud)
优化器是为了处理这种情况而构建的,所以请利用它!
我已将 更改count(1)为 a group by,因为您需要group by所有未聚合的列。
我假设您的实际查询比这更复杂,因为您选择的列可能相当于
select itemno, group
from item
where itemno = 12345
Run Code Online (Sandbox Code Playgroud)
您还可以用 an 相反 编写子查询analytic function。就像是count(*) over ( partition by group)。
顺便说一句,使用关键字作为列名,在本例中group是 A Bad Idea TM。它可能会引起很多混乱。正如您从上面的代码中看到的那样,里面有很多内容groups。
因此,根据我添加到问题中的 SQL-Fiddle,我认为您正在寻找类似以下内容的内容,这看起来并没有好多少。我怀疑,如果有时间,我可以让它变得更简单。另一方面请注意,明确的小写查询永远不值得它造成的麻烦。不过我遵循了你的命名约定。
with sub_query as (
select count(*) - count(icav.itemno) as error
, count(icav.itemno) as ok
, min(itemno) over () as itemno
, tariffgroup
, tariffno
from itemattribute ia
left outer join icav
on ia.attributeid = icav.attributeid
group by icav.itemno
, tariffgroup
, tariffno
)
select ic.itemno, ic.country, ic.imgroup, ic.imtariff
, sum(im.error) as "imerror", sum(im.ok) as "imok"
, ic.exgroup, ic.extariff
, sum(ex.error) as "exerror", sum(ex.ok) as "exok"
from itemcountry ic
left outer join sub_query im
on ic.imgroup = im.tariffgroup
and ic.imtariff = im.tariffno
and ic.itemno = im.itemno
left outer join sub_query ex
on ic.exgroup = ex.tariffgroup
and ic.extariff = ex.tariffno
and ic.itemno = ex.itemno
where ic.itemno = 12345
group by ic.itemno, ic.country
, ic.imgroup, ic.imtariff
, ic.exgroup, ic.extariff
;
Run Code Online (Sandbox Code Playgroud)