Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle:having子句中的命名子查询_Sql_Oracle_Subquery - Fatal编程技术网

Sql Oracle:having子句中的命名子查询

Sql Oracle:having子句中的命名子查询,sql,oracle,subquery,Sql,Oracle,Subquery,如何从having子句的子选择中引用网络列 ORA-00904:网络:标识符无效。如果省略最后一行,它将按预期工作,但我只对network>1的行感兴趣。首先,不能在同一查询中使用distinct和group by。这只是多余的,你是对的,我不知道oracle为什么不抛出异常 其次,别名与查询在同一级别上是未知的。您应该将其包含在外部查询中 select id, name, network from ( select c.id, c.name, ( select

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

ORA-00904:网络:标识符无效。如果省略最后一行,它将按预期工作,但我只对network>1的行感兴趣。

首先,不能在同一查询中使用distinct和group 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;

您无法访问在“选择入组人”、“拥有”或“位置”中定义的字段

sql运算符的顺序如下所示:

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

这就是为什么您可以按顺序使用网络,但不能在select之前的运营商中使用网络。

您正在尝试这样做吗

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_映射中是否有关联行,以及:

num_sources:公司所在的company_映射中的行数 消息来源。 num_targets:company_映射中 公司是目标。 num_mappings:映射源或目标的公司_中的连接数


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

您是否尝试过将网络更改为其他类型,例如AAA:invalid identifier-给出相同的错误代码。您的意思是distinct是冗余的?因为Oracle并不抱怨在我的示例中同时使用distinct和group by。如果c.id是company表上的主键,则group by是冗余的-如果不是,则最好在select表中应用子查询之前定义一个内联视图以返回distinct c.id和c.name。想一想,您最好去掉子查询,只需连接公司到公司的映射,使用having子句过滤聚合结果。+1回答不错!如果你放一个指向文档的链接会更好:你可以在这里看到MSSQL的顺序-。我相信Oracle的逻辑顺序是一样的。是的,这就是我所想的,但是如果可能的话,我会使用一个company_映射表并将两个连接条件都放在其中。我认为左连接也可以是一个内部连接。是的,我已经尝试过有两个左连接,但我肯定需要在一列中同时计算这两个连接的计数。@kosmičák,您可以用count*获得计数。由于我两次加入公司映射,您也可以很容易地获得源/目标的独立计数。@DavidAldridge,说得好!直到看到Bazz的解决方案,我才想到将它们合并为一个。但我认为我这样做只是为了提供另一种解决方案。他的解决方案和我的解决方案的执行计划会有所不同。@Ronnies不过,在company_映射中没有关联行的公司的count*=1而不是0,这是错误的,这里有些奇怪。。。我删除了having子句并运行了我的初始版本和你的版本,用一些有意义的东西替换了foobar,在我们的数据库中,你的查询需要30-40秒,我的查询不到2秒。另外,你的版本不会返回network=0的公司。区别可能是你的版本必须先创建一个巨大的笛卡尔产品,然后再选择那些名称为“foobar%”的产品,而在我的版本中,它首先选择那些foobar行,然后只为它们应用子选择?是的,没错。我使用join和not left join,因为count*必须大于1。如果您希望列表中的network=0,请使用left join。我想性能差的原因是Oracle没有在连接中使用索引。在公司id源和公司id目标上同时添加索引,或者将查询更改为使用索引。
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;
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