详解SQL嵌套子查询_Mssql数据库教程

编辑Tag赚U币
教程Tag:暂无Tag,欢迎添加,赚取U币!

推荐:详解SQL命令大全--中文翻译
SQL语句功能 -- 数据操作 SELECT--从数据库表中检索数据行和列 INSERT--向数据库表添加新数据行 DELETE--从数据库表中删除数据行 UPDATE--更新数据库表中的数据 -- 数据定义 CREATETABLE--创建一个数据库表 DROPTABLE--从数据库中删除表 ALTERTABLE--修改数

一些初级程序员常常对SQL语法中的子查询,由其对嵌套子查询(子查询中包含一个子查询)的使用比较生疏,本文就此做一个基本讲解,相信新手会有一定收获。
    使用子查询的原则
 
1.一个子查询必须放在圆括号中。 
  2.将子查询放在比较条件的右边以增加可读性。 
子查询不包含 ORDER BY 子句。对一个 SELECT 语句只能用一个 ORDER BY 子句, 
并且如果指定了它就必须放在主 SELECT 语句的最后。  
ORDER BY 子句可以使用,并且在进行 Top-N 分析时是必须的。 
  3.在子查询中可以使用两种比较条件:单行运算符和多行运算符。 

    子查询的类型 
单行子查询:从内 SELECT 语句只返回一行的查询 
多行子查询:从内 SELECT 语句返回多行的查询 

    单行子查询 
单行子查询是从内查询返回一行的查询。在该子查询类型中用一个单行操作符。幻灯片中列出了单行操作符。 

显示那些 job ID 与雇员 141 相同的雇员。 
SELECT last_name, job_id 
FROM employees 
WHERE job_id = 
(SELECT job_id 
FROM employees 
WHERE employee_id = 141); 

SELECT last_name, job_id, salary 
FROM employees 
WHERE job_id = 
(SELECT job_id 
FROM employees 
WHERE employee_id = 141) 
AND salary > 
(SELECT salary 
FROM employees 
WHERE employee_id = 143); 

显示 job ID 与雇员 141 相同,并且薪水 高于雇员 143 的那些雇员。 

注:外和内查询可以从不同的表中取得数据。 

SELECT last_name, job_id, salary 
FROM employees 
WHERE salary = 
(SELECT MIN(salary) 
FROM employees); 

求所有人谁的工资最小。 

SELECT department_id, MIN(salary) 
FROM employees 
GROUP BY department_id 
HAVING MIN(salary) > 
(SELECT MIN(salary) 
FROM employees 
WHERE department_id = 50); 

求每个部门的最小工资,但是要高于50号部门的工资。 

SELECT employee_id, last_name 
FROM employees 
WHERE salary = 
(SELECT MIN(salary) 
FROM employees 
GROUP BY department_id); 

问题出现在:单行子查询返回了多个查询值; 
应改为: 
SELECT employee_id, last_name 
FROM employees 
WHERE salary in 
(SELECT MIN(salary) 
FROM employees 
GROUP BY department_id);

SELECT last_name, job_id 
FROM employees 
WHERE job_id = 
(SELECT job_id 
FROM employees 
WHERE last_name = ’Haas’); 

如果子查询返回的是零值,不会对主程序造成影响; 
如果子查询返回的是空值,那么会影响主程序的返回值; 
SELECT employee_id, 
last_name 
FROM employees 
WHERE employee_id NOT IN 
(SELECT manager_id 
FROM employees) 

SELECT employee_id, 
last_name 
FROM employees 
WHERE employee_id NOT IN 
(SELECT manager_id 
FROM employees 
WHERE manager_id IS NOT NULL) 

放在select下的子查询的返回值必须是一个具体值, 
from后面也可以加子查询; 
having后面也可以加子查询; 
order by后面也可以; 

 

多列子查询适应于:成对比较;非成对比较。  

SELECT employee_id, manager_id, department_id  
FROM employees  
WHERE (manager_id, department_id) IN  
(SELECT manager_id, department_id  
FROM employees  
WHERE employee_id IN (178,174))  
AND employee_id NOT IN (178,174);  

输出:176 149 80  

只有要查询的东西和你子查询返回的东西一一对应上了,你的查询才能成功。  
如果有一个 对应不上那么你的查询不会成功。  

非成对的子查询:  
SELECT employee_id, manager_id, department_id  
FROM employees  
WHERE manager_id IN (SELECT manager_id  
FROM employees  
WHERE employee_id IN (174,141))  
AND department_id IN (SELECT department_id  
FROM employees  
WHERE employee_id IN (174,141))  
AND employee_id NOT IN(174,141);  

输出:144 124 50  
143 124 50  
142 124 50  
176 149 80  
上面两个程序就是成对子查询和非成对子查询两者之间的区别。  

如果我想去显示员工信息,要求:员工的工资高于本部门的平均工资。  
SELECT a.last_name,  
a.salary,  
a.department_id  
FROM employees a  
WHERE a.salary >  
(SELECT AVG(salary)  
FROM employees b  
WHERE b.department_id = a.department_id);  

in line view(内联视图)  

SELECT a.last_name, a.salary,  
a.department_id, b.salavg  
FROM employees a, (SELECT department_id,  
AVG(salary) salavg  
FROM employees  
GROUP BY department_id) b  
WHERE a.department_id = b.department_id  
AND a.salary > b.salavg;


数据分散于多个表中需要进行拼合
SELECT DISTINCT c.LastName, c.FirstName 
FROM Person.Contact c JOIN HumanResources.Employee e
ON e.ContactID = c.ContactID WHERE EmployeeID IN 
(SELECT SalesPersonID 
FROM Sales.SalesOrderHeader
WHERE SalesOrderID IN 
(SELECT SalesOrderID 
FROM Sales.SalesOrderDetail
WHERE ProductID IN 
(SELECT ProductID 
FROM Production.Product p 
WHERE ProductNumber LIKE 'FW123%')));

分享:揭秘SQL Server2000安全设置全攻略
Microsoft建立了一种既灵活又强大的安全管理机制,它能够对用户访问SQLServer服务器系统和数据库的安全进行全面地管理。按照本文介绍的步骤,你可以为SQLServer2000构造出一个灵活的、可管理的安全策略,而且它的安全性经得起考验。 一、验证方法选择 本文对

来源:模板无忧//所属分类:Mssql数据库教程/更新时间:2010-02-25
相关Mssql数据库教程