admin

了解基本的SQL查询

sql

我有一个查询

SELECT tran_number
  FROM table_a WHERE customer_id IN
          (SELECT customer_id 
             FROM table_b
            WHERE customer_key = 89564
                  AND (   other_phn_area_code
                       || other_phnum_pfx_num
                       || other_phnum_sfx_num IN
                          (123456789)))
       AND phn_area_code || phnum_pfx_num || phnum_sfx_num IN (123456789)

上面的代码工作正常。关注的是内部查询(下面单独复制了内部查询)…

(SELECT customer_id 
                 FROM table_b
                WHERE customer_key = 89564
                      AND (   other_phn_area_code
                           || other_phnum_pfx_num
                           || other_phnum_sfx_num IN
                              (123456789)))

当我执行此查询时,出现错误消息customer_id: invalid identifier。实际上,table_b没有任何名为的字段customer_id。如果是这样,那么当我将其用作上面的内部查询时,它是如何工作的,没有任何问题。

请帮助我理解这一点。

下面的数据库详细信息

Oracle 11G Enterprise edition 11.2.0.2.0
PL/SQL Release 11.2.0.2.0

阅读 144

收藏
2021-07-01

共1个答案

admin

这是 范围的问题 。Oracle会从最内层的子查询开始,并向外验证标识符。如果我们将表别名添加到您的原始查询中,则情况可能会变得更加清晰:

SELECT t1.tran_number 
  FROM table_a t1
  WHERE t1.customer_id IN 
          (SELECT t1.customer_id  
             FROM table_b t2 
            WHERE t2.customer_key = 89564 
                  AND (   t2.other_phn_area_code 
                       || t2.other_phnum_pfx_num 
                       || t2.other_phnum_sfx_num IN 
                          (123456789))) 
       AND t1.phn_area_code || t1.phnum_pfx_num || t1.phnum_sfx_num IN (123456789)

实际上,外部查询使用子查询作为EXISTS的测试,即仅检查CUSTOMER_KEY和其他列的给定值是否存在。如果这不是您想要的,则应在子查询中更改列名。(这是一个很好的选择:您可能会从主查询中得到令人困惑的结果,这就是为什么要单独调查子查询的原因)。

在这些情况下使用别名始终是一种好习惯。如果您对子查询使用了这样的别名:

....
  WHERE t1.customer_id IN 
          (SELECT t2.customer_id  
             FROM table_b t2 
            WHERE t2.customer_key = 89564 
....

该错误将立即显而易见。


SQLReference确实在子查询中解释了作用域的操作,但是很难找到。什么它说是这样的:

“ Oracle通过在子查询中命名的表中然后在父语句中命名的表中查找子查询中的不合格列”

您可以在PL / SQL文档中找到关于范围定义的更清晰的解释;SQL子查询以相同的方式工作。
了解更多

2021-07-01