sql中的无关子查询与相关子查询和集合查询详细举例说明

无关子查询

比较子查询:

例:查询与“小仙女”在同一个专业学习的学生信息

SELECT *  FROM student
WHERE specialty =
     (SELECT specialty  FROM  student WHERE sname='小仙女')

子查询不能用order by排序

例:查询C001号课的考试成绩比“小仙女”高的学生的学号和姓名

SELECT student.sno,sname 
FROM student,sc
WHERE student.sno = sc.sno and cno='C001' 
         and score>
          (SELECT score 
            FROM sc 
            WHERE cno='C001' and
           sno=(SELECT sno FROM student WHERE sname='小仙女')-- 找出学号
       )-- 找出成绩

ALL 、ANY(SOME )和IN子查询

运算符含义
ALL如果一系列的比较都为 TRUE,那么就为 TRUE。
ANY如果一系列的比较中任何一个为 TRUE,那么就为 TRUE。
SOME如果在一系列比较中,有些为 TRUE,那么就为 TRUE。
IN如果操作数等于表达式列表中的一个,那么就为 TRUE。

例:查询选修了“C001”号课程的学生姓名和所在专业

SELECT sname,specialty FROM student
WHERE sno IN
   (SELECT sno FROM sc  WHERE cno=’C001’)SELECT sname,specialty FROM student
WHERE sno = any
   (SELECT sno FROM sc  WHERE cno=’C001’)SELECT sname,specialty FROM student
WHERE sno = some
   (SELECT sno FROM sc  WHERE cno=’C001’)

子查询结果作为临时表

例:查询有2门以上课程的成绩在80分以上的学生的学号、姓名、年级和专业

SELECT s.sno,sname,grade,specialty FROM student s,
      (SELECT sno FROM SC where score >80 GROUP BY sno having COUNT(*)>2) ss
WHERE s.sno=ss.sno 
  • 这题用相关子查询的方法同样可解
SELECT sno,sname,grade,specialty FROM student s
   WHERE (SELECT COUNT(*) FROM sc WHERE sc.sno=s.sno and score >80)>2

相关子查询

比较子查询

查询成绩比该课的平均成绩低的学生成绩信息

SELECT * FROM  sc a  
WHERE score< ( SELECT avg(score)  FROM sc b WHERE a.cno=b.cno)

注意聚合函数必须搭配select语句使用不能单独使用

EXISTS子查询

  • EXISTS代表存在量词Э,它允许高效地检查指定查询是否产生某些行。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值TRUE或逻辑假值FALSE。

例:查询所有选修了C004号课程的学生姓名

SELECT sname 
FROM student
WHERE EXISTS(SELECT * FROM sc WHERE sno=student.sno 
AND cno='C004')
  • 注意:EXISTS的子查询只返回真值或假值, 给出列名无实际意义,故一般用xing号。

查询没有选修C004号课程的学生姓名

SELECT Sname  FROM Student
WHERE NOT EXISTS
         (SELECT *   FROM SC
          WHERE Sno = Student.Sno AND Cno='C004')

注意所有方法不唯一

  • 若子查询的查询结果非空,则EXISTS为真,否则为假。
  • NOT EXISTS 查询结果非空则为假,空则为真。

查询选修了全部课程的学生姓名

  • 选修了全部课程 ⟺ 没有一门课是他(她)不选的
select name
FROM Student
WHERE NOT EXISTS (SELECT *
                  FROM Course 
				  WHERE NOT EXISTS (SELECT * 
	                                FROM SC
	                                WHERE SNO=Student.SNO 
	                                AND CNO=Course.CNO)
                  )

在相关子查询中一层相当于一层for循环会把每一层的每一个元素都遍历一遍
[[sql查询基本知识#sql语句执行顺序|sql语句执行顺序]]

集合查询

并查询

Select语句 
            UNION [ ALL ] 
Select语句 

例:查询选修了课程C001或选修了课程C004的学生的学号:

其它方法:
SELECT distinct sno FROM sc
WHERE cno='C001' or cno='C004'SELECT distinct sno FROM sc 
WHERE cno in ('C001','C004')

SELECT sno FROM sc WHERE cno='C001'
UNION
SELECT sno FROM sc WHERE cno='C004'

交查询

查询选修了课程C001又选修了课程C004的学生的学号

SELECT sno FROM sc WHERE cno='C001'
INTERSECT
SELECT sno FROM sc WHERE cno='C004'

其它实现方法:
SELECT a.sno 
FROM sc a,sc b
WHERE a.sno=b.sno and a.cno='C001' and b.cno='C004'SELECT sno 
FROM sc 
WHERE cno='C001' and sno in 
( 
   SELECT sno FROM sc WHERE cno='C004'
)

差查询

查询选修了课程C001但没有选修课程C004的学生的学号

SELECT sno FROM sc WHERE cno='C001'
EXCEPT
SELECT sno FROM sc WHERE cno='C004'

其他方法:
SELECT sno FROM sc 
WHERE cno='C001' and sno not in 
( 
  SELECT sno FROM sc WHERE cno='C004'
)
<think>嗯,用户想要了解高级SQL查询的总结。我需要先确定用户的基础,可能已经掌握了基本的SELECT、WHERE、JOIN等操作,现在想深入更复杂的查询技巧。首先,我得回忆一下高级SQL通常包括哪些内容,比如窗口函数、CTE、子查询优化、递归查询、PIVOT/UNPIVOT,还有性能优化相关的内容。 然后,用户提到的系统级指令要求数学表达式用$...$,但这里是SQL,可能用上太多数学符号,过要注意如果有举例中的计算,比如行数计算,可能需要用到。过主要得确保结构清晰,分点说明,用中文回答。 接下来,得考虑用户可能的实际应用场景。高级SQL常用于数据分析、报表生成、复杂业务逻辑处理,所以需要结合实际例子说明每个高级功能的用途。比如窗口函数在排名、累计求的应用,CTE在递归查询中的使用,如何优化子查询的性能。 同时,要注意用户可见的格式要求,比如独立公式用$$...$$,但SQL示例代码应该用代码块,过用户没有特别提到代码块的格式,可能只需要正常分段。过通常回答技术内容时,代码示例会用反引号或者缩进,这里可能需要根据平台的支持情况处理,但用户没有特别要求,所以保持清晰即可。 另外,需要检查是否有常见的误区,比如窗口函数GROUP BY的区别,CTE的递归限制,EXISTSIN的性能差异等。这些点对于用户深入理解高级查询很重要。 可能还需要涵盖一些高级JOIN用法,比如自连接、交叉连接,以及集合操作符UNION、INTERSECT等。此外,动态SQL存储过程也可能属于高级内容,但或许用户更关注查询部分,暂时涉及编程。 最后,确保每个部分都有实际示例,帮助用户更好地理解概念。例如,在讲解窗口函数时,给出一个排名示例,用具体的SQL语句展示如何使用ROW_NUMBER()。在CTE部分,演示如何递归查询组织结构树。 总结结构大概分为几个部分:窗口函数、CTE、子查询优化、递归查询、PIVOT/UNPIVOT、集合操作、性能优化技巧。每个部分简要说明概念、语法应用场景,附上示例代码。这样用户能逐步了解每个高级功能的作用用法。 还要注意术语的准确性,比如窗口函数中的PARTITION BYORDER BY的作用,CTE的临时结果集特性,递归WITH的使用条件。同时,提醒用户在使用高级功能时注意数据库兼容性,比如数据库MySQL、PostgreSQLSQL Server)对某些语法的支持可能同。 最后检查是否有遗漏的重要高级主题,比如物化视图、分区表、索引优化策略,过这些可能偏向数据库设计,而用户问题更侧重于查询,所以可能需要深入。但如果有相关查询优化技巧,还是可以提及,比如避免在WHERE子句中使用函数,以减少全表扫描。 现在,把这些整理成结构清晰的回答,分点列出,每个部分用小标题,示例代码用代码块,确保语法正确,符合用户的要求。</think>### 高级 SQL 查询总结 以下是高级 SQL 查询的核心知识点技巧总结,结合实际场景示例说明,帮助提升复杂数据处理能力。 --- #### 一、窗口函数(Window Functions) **用途**:对数据集的子集(“窗口”)进行计算,改变原始行数。 **语法**: ```sql 函数名() OVER (PARTITION BY 列 ORDER BY 列 [ROWS/RANGE 范围]) ``` **常用函数**: 1. **排名函数** - `ROW_NUMBER()`:生成唯一行号(如:1,2,3)。 - `RANK()`:允许并列排名(如:1,1,3)。 - `DENSE_RANK()`:允许并列且无间隔排名(如:1,1,2)。 **示例**:按部门分组计算薪资排名 ```sql SELECT name, department, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank FROM employees; ``` 2. **聚合函数** - `SUM()`, `AVG()`, `COUNT()` 等支持窗口计算。 **示例**:计算累计销售额 ```sql SELECT order_date, amount, SUM(amount) OVER (ORDER BY order_date) AS cumulative_sum FROM orders; ``` --- #### 二、公共表表达式(CTE, Common Table Expressions) **用途**:定义临时结果集,提升复杂查询的可读性复用性。 **语法**: ```sql WITH cte_name AS ( SELECT ... ) SELECT * FROM cte_name; ``` **递归 CTE**:处理层次结构数据(如树形结构)。 **示例**:查询组织层级关系 ```sql WITH RECURSIVE org_tree AS ( SELECT id, name, manager_id FROM employees WHERE manager_id IS NULL -- 根节点 UNION ALL SELECT e.id, e.name, e.manager_id FROM employees e INNER JOIN org_tree ot ON e.manager_id = ot.id ) SELECT * FROM org_tree; ``` --- #### 三、子查询优化 1. **相关子查询 vs 非相关子查询** - **相关子查询**:依赖外部查询的值,逐行执行,性能较差。 - **非相关子查询**:独立执行,优先优化为 JOIN。 2. **使用 EXISTS 替代 IN** - `EXISTS` 在找到匹配项后立即终止,效率更高。 **示例**: ```sql SELECT * FROM orders o WHERE EXISTS ( SELECT 1 FROM customers c WHERE c.id = o.customer_id AND c.country = 'USA' ); ``` --- #### 四、高级 JOIN 技巧 1. **自连接(Self Join)** **示例**:查找同一部门的员工对 ```sql
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值