SQL - 子查询,子查询版数据分页与高效的数据分页函数 160

SQL - 子查询,子查询版数据分页与高效的数据分页函数 160

编码文章call10242025-02-01 3:53:0410A+A-

#头条创作挑战赛#

子查询

子查询:在一个查询语句中嵌套另一个查询语句,也称叫做嵌套查询或内部查询;子查询可用于主查询的各个地方如被当做数据源,数据列,查询条件等,从而实现更加复杂的查询需求;被当作结果集的查询语句被称为子查询

子查询可分为两类:

A 独立子查询:子查询的语句可以独立执行得到结果,不依赖其他查询语句

B 相关子查询:子查询语句中会引用父查询语句中的数据即无法单独执行获取结果

1 独立子查询

示例1:子查询结果作为主查询的数据源与数据列

--查询Student表中姓名,班级,年龄,性别列的数据
SELECT  SName,SCId,SAge,SGender
FROM dbo.Student
--使用子查询将上面的查询结果作为子查询的数据源
SELECT * FROM
(
  SELECT
    SName AS N'学生姓名',
    SCId AS N'班级编号',
    SAge AS N'学生年龄',
    SGender AS N'学生性别'
  FROM dbo.Student
) AS s1
WHERE s1.学生性别=1
--注意:此时的条件判断不能再使用之前的 SGender
--因为子查询的结果集中已没有了 SGender 字段
--只有 学生性别 字段,作为主查询的 数据列

--上面8-13行的子查询语句可单独执行得到结果

2 相关子查询

2.1 使用>, <, =, >=, <=,in等符号的相关子查询

--通过子查询中的班级名称,查询名称为秦的编号,得到一个查询语句的结果
SELECT CId FROM dbo.Class WHERE CName=N'秦'
--子查询只有返回且仅返回一行、一列数据的
--子查询被叫做 单值子查询
SELECT * FROM dbo.Student
WHERE SCId=(SELECT CId FROM dbo.Class WHERE CName=N'秦')
--上面子查询只返回一个班级编号

--子查询得到多个结果叫做 列值子查询
--子查询返回多个结果
SELECT CId FROM dbo.Class WHERE CId<5
SELECT * FROM dbo.Student
WHERE SCId in (SELECT CId FROM dbo.Class WHERE CId<5)
--in 相当于 scid in(2,3,4) 或者 scid=2 or scid=3 or scid=4 
--即之前说的列值(一个结果集合)

2 通过exists()语句 实现相关子查询

--exists()语句只要语句中的查询结果返回一条及以上的数据
--返回值为true 反之为false
--exists()语句的测试
IF EXISTS(SELECT * FROM dbo.Student)--有返回数据
PRINT 'true'  
ELSE
PRINT 'false'
PRINT '===================================='
IF EXISTS(SELECT * FROM dbo.Student WHERE SCId=0)--无返回数据
PRINT 'true'
ELSE
PRINT 'false'

--注意:exists()语句中的查询语句中只要查询到一条数据
--就不会继续向下查询,相当于C#中逻辑判断的短路(与/或都有)
如逻辑&&中的短路,代码如下
int num1 = 3, num2 = 5;
if (num1 > 5 && num2 >= 6)
{
  Console.WriteLine("逻辑&表达式中的短路");
}
3 > 5 条件为假与 &&一起使用 后面的条件不再判断
使用 && 连接,需要两个条件都为真 整个条件才能成立,
第一个条件都不成立 后一个条件不再判断
本是系统所做的优化的好事,却成了幸福的烦恼

示例2:查询班级名称为 '汉' 的学生信息

SELECT * FROM dbo.Student WHERE 
EXISTS
(
  SELECT * FROM dbo.Class
  WHERE CName=N'汉' AND CId=dbo.Student.SCId
)
--既使用班级表的 CId 又使用了 学生表的 SCId
--exists()语句中的查询语句无法单独执行
--需要依赖主查询的当前 Student.SCId

子查询分页

1)查询出当前页码 2)获取当前页码及之前的所有数据 3)通过子查询去除不要的数据

--表中共有24条数据
SELECT COUNT(*) FROM dbo.Student
--数据分页的原理
--假设每页 5条数据
--第一页数据,需要进行排序,而后使用top获取前5条数据
--(1*5) 1 表示页码  5 表示页容量即每页多少数据
SELECT TOP (1*5) * FROM dbo.Student ORDER BY SId
--查询出前2页的数据
SELECT TOP (2*5) * FROM dbo.Student ORDER BY SId
--查询第2页的数据
--通过子查询去除第一页的数据
select * from
(
	select top (5*2) --前2页数据
	* --显示所有列名
	from dbo.Student order by SId asc
) as stu
where stu.SId not in
(
	--查询出第一页的用户Id
	select top 5 SId
	from  dbo.Student
	order by SId asc
)

简单来说就是去除当前页码之前的所有数据
只保留本页码中的数据(暂时了解)

高效数据分页函数

在sql server 的2005版本中新增了一个高效的 row_number()数据分页函数

--3高效的数据分页函数 row_number() 之后会详说
--每页 5 条数据,获取第三页的数据
select top 5 * from 
(
	select  --多新增了一个排好序的名为 行号 的列
	row_number() over(order by SId asc) as 行号, 
	* 
	from dbo.Student
) as stu
--获取包含行号在 10-15的数据
where stu.行号 between (3-1)*5+1 and 3*5 
order by stu.SId

--对比数据
SELECT * FROM dbo.Student
点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4