Oracle:在having子句中命名子查询

时间:2013-05-15 08:30:05

标签: sql oracle subquery

如何从子句中的子选择中引用网络列?

select distinct c.id, c.name,
(
select count(cm.id) cnt
from
company_mapping cm
where
cm.company_id_source = c.id
or
cm.company_id_target = c.id
) network
from company c
where
c.name like 'foobar%'
group by c.id, c.name
having network > 1

ORA-00904:“NETWORK”:标识符无效。如果我遗漏了最后一行,它按预期工作,但我只对网络>行感兴趣1。

4 个答案:

答案 0 :(得分:9)

您无法访问selectgroup byhavingwhere中定义的字段。

sql运算符的顺序如下:

1.FROM clause
2.WHERE clause
3.GROUP BY clause
4.HAVING clause
5.SELECT clause
6.ORDER BY clause 

这就是为什么你可以在network中使用order by但在select之前的运算符中不能使用{。}}。

答案 1 :(得分:3)

你想做这样的事吗?

select c.id
      ,c.name
      ,count(*) 
      ,count(s.company_id_source) as num_sources
      ,count(t.company_id_target) as num_targets
  from company              c
  left join company_mapping s on(s.company_id_source = c.id)
  left join company_mapping t on(t.company_id_target = c.id)
 where c.name like 'foobar%'  
 group 
    by c.id
      ,c.name
having count(s.company_id_source) > 1
    or count(t.company_id_target) > 1;

修改: 下面的新查询以回应评论。 该查询现在返回:所有匹配“Foobar”的公司,无论他们是否在表company_mapping中都有关联的行,以及:

  • num_sources:公司所在的company_mapping中的nr行 来源。
  • num_targets:company_mapping中行的nr 公司是目标。
  • num_mappings:company_mapping(源或目标)中的“连接”nr

select c.id
      ,c.name
      ,count(s.company_id_source) + count(t.company_id_target)   as num_mappings
      ,count(s.company_id_source) as num_sources
      ,count(t.company_id_target) as num_targets
  from company              c
  left join company_mapping s on(s.company_id_source = c.id)
  left join company_mapping t on(t.company_id_target = c.id)
 where c.name like 'foobar%'  
 group 
    by c.id
      ,c.name;

答案 2 :(得分:3)

Ronnis在正确的道路上,但查询实际上应该更简单。 请尽量避免选择内部选择,因为它在99%的时间都是性能杀手。

select c.id
,      c.name
,      count(*) network
from   company c
join   company_mapping cm on c.id in (cm.company_id_source, cm.company_id_target)
where  c.name like 'foobar%'
group by c.id, c.name
having count(*) > 1

答案 3 :(得分:2)

首先,你不能在同一个查询中拥有distinctgroup by这只是多余的,你是对的,我不知道为什么oracle没有'抛出异常。

其次,别名与查询在同一级别是未知的。你应该将它包含在外部查询中。

select id, name, network
from (
    select c.id, c.name,
      (
      select count(cm.id) cnt
      from
      company_mapping cm
      where
      cm.company_id_source = c.id
      or
      cm.company_id_target = c.id
      ) network
    from company c
    where
    c.name like 'foobar%'
    group by c.id, c.name
)
WHERE network > 1;