GZICP.com   
 
    返回首页
    联系我们
 
 
     

SQL入门:相关子查询

www.gzicp.com   2004年7月9日 17:22:25
 
  允许引用先前提到的任
表的相关引用。
何表的子查询称为相关子查询。

我们也说该子查询具有对主查询中


  下列示例是一个不相关
雇员的雇员编号和姓名:
子查询,该子查询列出部门 'A0

0' 中薪水超过该部门平均薪水的


                                                                               
   SELECT EMPNO, LASTNAME                        
   FROM EMPLOYEE                                    
   WHERE WORKDEPT = 'A00'                  
   AND SALARY > (SELECT AVG(SALARY)


  
FROM EMPLOYEE
   WHERE
WORKDEPT = 'A00')

  如果想要知道每个部门的平均薪水,
标识的表的每一行,各使用一次 SQL 的
就可做到这一点。此类型的相关子查询用
询中计算谓词所需要的。
则需要对每个部门计算一次子查询。对在外层查询中
相关功能(该能力允许您编写重复执行的子查询),
来计算外层表的每一行的某个特性,该特性是在子查


  此示例显示薪水高于部门平均薪水的所有雇员:                                   

                                                                               

   SELECT E1.EMPNO
, E1.LASTNAME, E1.WORKDEPT
   FROM EMPLOYEE E1                              
   WHERE SALARY > (SELECT AVG(SALARY)

   FROM
EMPLOYEE E2
  
WHERE E2.WORKDEPT = E
1.WORKDEPT)
   ORDER BY E1.WORKDEPT                      

  在此查询中,对每个部门计算一次子查询。结果为:                                
   

  要编写带有相关子查询
,在外部查询的 FROM 子句
关名限定的列引用。例如,
的工作部门值。在外部查询
的查询,使用与带有子查询的普
中,只是在表名后面放置一个相
如果 E1 是相关名,则 E1.WORK
中对表的每一行(概念上)重新
通外部查询相同的基本格式。然而
关名。于是子查询可能包含由该相
DEPT 表示外部查询中表的当前行
计算子查询。

  通过使用相关子查询,可以使系统为您工作并减少需要在应用程序中编写的代码量。   

  DB2 中允许非限定相关
SALES 有一个命名为 SALES
引用。例如,表 EMPLOYEE 有一
_PERSON 的列,但没有命名为 L
个命名为 LASTNAME 的列,表
ASTNAME 的列。

                                                                               
   SELECT LASTNAME, FIRSTNME, COMM      
   FROM EMPLOYEE                                    
   WHERE 3 > (SELECT AVG(SALES)

   FROM SALES              
   WHERE LAST
NAME = SALES_PERSON)

  在此示例中,系统检查最内层的 FRO
LASTNAME 列,则系统检查次最内层的 FR
是必要的,还是建议限定相关引用以改进
M 子句,以获取 LASTNAME 列。如果未找到
OM 子句(此情况下为外部 FROM 子句)。虽然不总
查询的可读性并确保获取想要的结果。


  实现相关子查询                                                                


  想何时使用相关子查询?列函数的使用有时是一条线索。                           

  假定您想要列出教育级别高于部门平均值的雇员。                                 

  首先,您必须确定选择
EMPLOYEE 表中的 EMPNO 应
WORKDEPT 说明为条件。当
明解法。现在可构造查询的
列表项。问题为 "List the emp
该足以唯一标识雇员。该问题也
问题未明确要求显示列时,在选
一部分:
loyees"。这隐含着来自
将 EDLEVEL 和雇员的部门
择列表中包括这些列将会有助于说


   SELECT LASTNAME, WORKDEPT, EDLEVEL
   FROM EMPLOYEE                                    

  接着需要搜索条件(WH
higher than the average
,必须计算该雇员所在部门
某个特性(当前雇员所在部
ERE子句)。问题语句为 "...wh
for that employee's departme
的平均教育级别。此语句适合相
门的平均教育级别)。 EMPLOYE
ose level of education is
nt"。这意味着对于表中每个雇员
关子查询的说明。正在对每行计算
E 表需要相关名:

   SELECT LASTNAME, WORKDEPT, EDLEVEL
   FROM EMPLOYEE E1                              

  需要的子查询较简单。该子查询计算
每个部门的平均教育级别。完整的 SQL 语句为:

   SELECT LASTNAME, WORKDEPT, EDLEVEL
   FROM EMPLOYEE E1                              
   WHERE EDLEVEL > (SELECT AVG(EDLEVEL)


  
FROM EMPLOYEE E2
  
WHERE E2.WORKDEPT =
E1.WORKDEPT)

  结果为:                                                                      
   


  假定不列出雇员的部门编号,则应列出部门名称。需要的信息(DEPTNAME)在独立表(DEPARTMENT)中。定义相关变量的外层查询也可以是连接查询 (参见从多个表中选择数据以了解详情)点击查看。


  当在外层查询中使用连接时,列出要
的任何一个表名旁边。
在 FROM 子句中连接的表,并将相关名放在这些表名


  要修改查询以列出部门
。 FROM 子句现在也必须包
名称而不是部门编号,在选择列
括 DEPARTMENT 表,并且 WHERE
表中用 DEPTNAME 替换 WORKDEPT
子句必须表示适当的连接条件。

  以下是修改的查询:                                                           

   SELECT LASTNAME, DEPTNAME, EDLEVEL
   FROM EMPLOYEE E1, DEPARTMENT      
   WHERE E1.WORKDEPT = DEPA
RTMENT.DEPTNO
   AND EDLEVEL > (SELECT AVG(EDLEVEL)


  
FROM EMPLOYEE E2
  
WHERE E2.WORKDEPT = E1
.WORKDEPT)

  上例显示,必须在包含相关子查询的
。然而,这种包含可能涉及若干层嵌套。
某个查询的 FROM 子句中定义用于子查询中的相关名


  假定某些部门只有几个
了使平均教育级别在用于比
此现在必须列出教育级别高

雇员,因此这些部门的平均教育
较雇员时是有意义的数字,一个
于雇员所在部门平均值的雇员,

级别可能是错误的。可以决定,为
部门中必须至少有 5 个雇员。因
并只考虑至少有 5 个雇员的部门


  该问题暗含另一个子查询,因为对于
的雇员总数:
外层查询中每个雇员来说,必须计算该雇员所在部门


   SELECT COUNT(*)                                      
   FROM EMPLOYEE E3                              
   WHERE E3.WORKDEPT = E1.WORKDEPT

  仅当计数大于或等于 5 时才计算平均值:                                     

   SELECT AVG(EDLEVEL)                              
   FROM EMPLOYEE E2                              
   WHERE E2.WORKDEPT = E1.WORKDEPT
   AND 5 <= (SELECT COUNT(*)

   FROM EMPLOYEE E3  
   WHERE E3.WO
RKDEPT = E1.WORKDEPT)

  最后,只包括其教育级别高于部门平均值的那些雇员:                             

   SELECT LASTNAME, DEPTNAME, EDLEVEL
   FROM EMPLOYEE E1, DEPARTMENT      

   WHERE E1.WOR
KDEPT = DEPARTMENT.DEPTNO
   AND EDLEVEL >

   (SELECT AVG(EDLEVEL)                      
   FROM EMPLOYEE E2                      

   WHERE E2
.WORKDEPT = E1.WORKDEPT
   AND 5 <=

   (SELECT COUNT(*)                      
   FROM EMPLOYEE E3              
   WHERE E3.WORKDEP
T = E1.WORKDEPT))

  此语句产生下列结果:                                                         
   

 

ChinaITLab 

相关文章
·SQL入门:相关名(2004年07月09日)
·SQL入门:表表达式(2004年07月09日)
·SQL入门:条件表达式(2004年07月09日)
·SQL入门:转换数据类型(2004年07月09日)
·SQL入门:标量全查询(2004年07月09日)
·SQL入门:分组(2004年07月09日)
·SQL入门:使用函数(2004年07月09日)
·SQL入门:使用子查询(2004年07月09日)
·SQL入门:从多个表中选择数据(2004年07月09日)
·SQL入门:给表达式命名(2004年07月05日)
·SQL入门:使用表达式来计算值(2004年07月05日)
·SQL入门:运算次序(2004年07月05日)
·SQL入门:除去重复行(2004年07月05日)
·SQL入门:将行进行排序(2004年07月05日)
·SQL入门:选择行(2004年07月05日)
·SQL入门:选择列(2004年07月05日)
·SQL入门:创建视图(2004年06月30日)
·SQL入门:删除数据(2004年06月30日)
·SQL入门:更改数据(2004年06月30日)
·SQL入门:插入数据(2004年06月30日)
·SQL入门:创建表(2004年06月30日)
·SQL入门:数据类型(2004年06月28日)
·SQL入门:模式(2004年06月28日)
·SQL入门:视图(2004年06月28日)
·SQL入门:表(2004年06月28日)
最新文章
·防范SQL注入式攻击  (2004年09月05日)
·SQL injection的实现与应用  (2004年09月04日)
·SQL入门:目录视图的介绍  (2004年07月15日)
·SQL入门:大对象 (LOB)  (2004年07月15日)
·SQL入门:用户定义函数  (2004年07月15日)
·SQL入门:用户定义类型  (2004年07月15日)





 
 
Copyright © 1999-2008 GZICP.com All Rights Reserved