8

如何使用 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

我想在子查询中更改WHERE Attribute.ItemNo=12345WHERE Attribute.ItemNo=Item.ItemNo,但我不知道这是否可能。我不断收到“ORA-00904: 'Item'.'ItemNo': Invalid Identifier”

编辑:

好的,这就是为什么我需要这种结构:

我希望能够获得“错误”记录(项目缺少值)和“OK”记录(项目有值)的计数。

我在小提琴中设置的方式返回正确的数据。我想我最终可能只是填写每个子查询中的值,因为这可能是最简单的方法。对不起,如果我的数据结构有点复杂。如果需要,我可以解释。

我的桌子是:

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) );

到目前为止我的查询是:

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;

它也在SQL Fiddle中设置。

4

2 回答 2

1

您可以在子查询中执行此操作,但不能在联接中执行此操作。在你的情况下,我认为没有必要。您可以将其置于连接条件中。

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

优化器是为处理这种情况而构建的,所以利用它!

我已将count(1)a更改group by为您需要的group by所有未聚合的列。

我假设您的实际查询比这更复杂,因为您选择的列可能相当于

select itemno, group
  from item
 where itemno = 12345

您也可以用 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
           ;
于 2012-04-10T18:15:56.087 回答
-4

您可以将 WHERE attribute.itemno=item.itemno 放在子查询中。无论如何,您都要过滤数据,过滤子查询中的数据通常也更快。

于 2012-04-10T16:40:34.877 回答