Oracle如何使SELECT INSIDE A SELECT工作?

vohkndzv  于 2023-01-16  发布在  Oracle
关注(0)|答案(5)|浏览(111)

只是想知道为什么下面的选择不工作:

SELECT 
    A.FIELD1
     , (SELECT PCN FROM (select B.PRIORITY, B.PCN 
                        from
                        TABLE2 B 
                        WHERE B.CUST= A.CUST 
                        ORDER BY B.PRIORITY) 
         WHERE ROWNUM = 1) AS PCN 
  FROM TABLE1 A;

第2行错误:ORA-00904:"A"。"客户":无效标识符
值得注意的是:

  • 表1具有字段FIELD1、CUST。
  • 表2具有字段PCN、优先级、客户。

先谢了。

ttcibm8c

ttcibm8c1#

你的查询不应该给你这个错误消息,当你删除外部的qery就会发生这种情况

CREATE tABLE TABLE1  (FIELD1 int, CUST int)
INSERT INTO TABLE1 VALUES(1,1)
CREATE TABLE TABLE2 (PCN int, PRIORITY int, CUST int)
INSERT INTO TABLE2 VALUES (1,1,1)
SELECT 
    A.FIELD1
     , (SELECT PCN FROM (select B.PRIORITY, B.PCN 
                        from
                        TABLE2 B 
                        WHERE B.CUST= A.CUST 
                        ORDER BY B.PRIORITY) 
         WHERE ROWNUM = 1) AS PCN 
  FROM TABLE1 A;

| 字段1|多氯联苯|
| - ------|- ------|
| 1个|1个|
fiddle

q3qa4bjr

q3qa4bjr2#

嵌套内联选择(多于一层)时,内部嵌套选择引用父块的能力将无法保持。因此,由于这种嵌套,您对TABLE2的查询无法看到TABLE1中的列。
试试这个:

SELECT a.field1,
       pcn.pcn
  FROM table1 a,
       (SELECT b.cust,
               b.priority,
               b.pcn,
               ROW_NUMBER() OVER (PARTITION BY b.cust ORDER BY b.priority DESC) seq
          FROM table2 b) pcn
 WHERE a.cust = pcn.cust(+)
   AND pcn.seq(+) = 1

这对于报表查询非常有效。如果您最终针对特定客户添加了过滤器,那么如果您有足够新的Oracle版本支持OUTER APPLY,那么您最好使用OUTER APPLY。

xuo3flqw

xuo3flqw3#

你可以试试这个:

SELECT 
A.FIELD1
 , (SELECT B.PCN 
                    from
                    TABLE2 B 
                    WHERE B.CUST= A.CUST 
                    ORDER BY B.PRIORITY
     FETCH FIRST 1 ROWS ONLY) AS PCN 
FROM TABLE1 A;

获取前1行只获取第一个有序记录。适用于12c及以上,支持嵌套,不需要第二个子查询。

u91tlkcl

u91tlkcl4#

另一种选择可能是CTE。
样本数据:

SQL> with
  2  table1 (field1, cust) as
  3    (select 1, 100 from dual union all
  4     select 2, 200 from dual
  5    ),
  6  table2 (pcn, priority, cust) as
  7    (select 10, 1, 100 from dual union all
  8     select 20, 2, 100 from dual union all
  9     select 30, 1, 200 from dual
 10    ),

查询从这里开始。按优先级对行排序,然后获取排序最高的行(第20行):

11  temp as
 12    (select a.field1,
 13         b.pcn,
 14         rank() over (partition by a.field1 order by b.priority desc) rnk
 15     from table1 a join table2 b on a.cust = b.cust
 16    )
 17  select field1,
 18         pcn
 19  from temp
 20  where rnk = 1;

    FIELD1        PCN
---------- ----------
         1         20
         2         30

SQL>
3df52oht

3df52oht5#

您可以使用first聚合函数来实现相同的功能(假设您具有完全确定性的order by),而无需嵌套子查询:

select
  a.field1
  , (
    select max(b.pcn) keep(dense_rank first order by b.priority)
    from table2 b
    where b.cust = a.cust
  ) as pcn
from table1 a

对于这个样本数据

insert into table1 values(1,1);
insert into table1 values(2,2);
insert into table2 values(1,1,1);
insert into table2 values(2,2,1)

退货
| 字段1|多氯联苯|
| - ------|- ------|
| 1个|1个|
| 第二章|(无)|
SQL小提琴

相关问题