第七章、高级数据库查询

第七章、高级数据库查询

内容提要:

1. 掌握一般数据查询功能扩展

2. 掌握查询的并、交、差运算

3.掌握子查询的使用

4.了解其他一些查询功能

第一节 一般数据查询功能扩展

1.1. SELECT语句

//SQL的一般查询语句
SELECT [DISTINCT] [TOP n] select_list
//将查询的结果插入到了一个表中
[INTO new_table]
//需要查询的表
[FROM table_source]
//查询的条件
[WHERE search_conditition]
//对查询的结果进行分组
[GROUP BY group_by_expression]
//指定组或聚合函数的查找条件
[HAVING search_condition]
//对查询的结果进行排序
[ORDER BY order_expression [ASC|DESC]]
//对查询结果结果后面生成汇总数据行
[COMPUTE expression] 

1.2.使用TOP限制结果集

TOP n [percent][WITH TIES]

? Top n 前n行

? Top n [percent]前n%行

? [WITH TIES]:包括最后一行取值并列的结果。

例题:

【例1】查询单价最高的前三种商品的商品名、商品类别和单价,包括并列情况。

SELECT TOP 3 WITH TIES GoodsName, GoodsClassName,SaleUnitPrice,FORM Table_Goods a JOIN Table_GoodsClass b
ON a.GoodsClassID=b.GoodsClassID ORDER BY SaleUnitPrice DESC

1.3.使用CASE函数

  • 分情况显示不同类型的数据。CASE函数是一种多分支表达式。
  • 两种类型:
  1. 简单CASE函数
  2. 搜索CASE函数

语法:

CASE
 WHEN 布尔表达式1 then 结果表达式1
 WHEN 布尔表达式2 then 结果表达式2
 ……
 WHEN 布尔表达式n then 结果表达式n
 [ELSE 结果表达式n+1]
END

案例:

分析下列语句的作用(P110)

SELECT a.GoodsID,商品销售类别=CASE
WHEN COUNT(b.GoodsID)>10 THEN ‘热门商品’
WHEN COUNT(b.GoodsID)BETWEEN 5 AND 10 THEN ‘一般商品’
WHEN COUNT(b.GoodsID)BETWEEN 1 AND 4 THEN ‘难销商品’
ELSE ‘滞销商品’
END
FROM Table_Goods a LEFT JOIN Table_SaleBillDetail b
ON a.GoodsID=b.GoodsID GROUP BY a.GoodsID

1.4.将查询结果保存到新表中

SELECT 查询列表序列 INTO

FROM 数据源……(其他行过滤、分组语句)

注意:表名前加#为局部临时表,##为全局临时表,只有表名为永久表。

临时表只能当前查询可用

例子:SELECT * INTO #HD_Customer FROM Table_Customer WHERE ……

第二节 查询结果的并、交、差运算

2.1.并运算

  • 并运算(UNION):将多个查询结果合并为一个结果集。。
  • 语法:
SELECT 语句1
    UNION [ALL]
SELECT 语句2
    UNION [ALL]
 ……

使用UNION注意:

  • 要进行合并的查询,SELECT中列数必须相同,语义相同。
  • 每个相对应列的数据类型隐式兼容,如char(20)与varchar(40)。
  • 合并后结果采用第一个SELECT语句的列标题。
  • 若需排序,则GROUP BY语句写在最后一个SELECT之后,且排序的语句是第一个SELECT中的列名。

2.2.交运算

  • 交运算:返回同时在两个集合中出现的记录。
  • 语法:
SELECT 语句1
    INTERSECT
SELECT 语句2
    INTERSECT ……
SELECT 语句n

2.3.差运算

  • 差运算:返回第一个集合中有而第二个集合中没有的的记录。
  • 语法:
SELECT 语句1
EXCEPT
SELECT 语句2
EXCEPT……
SELECT 语句n

第三节 相关子查询

  • 子查询是一条包含在另一条SELECT语句里的SELECT语句。外层的SELECT语句叫外层查询,内层的SELECT语句叫内层查询(或子查询)。
  • 子查询总是写在圆括号中。

包括子查询的SELECT语句主要采用以下格式中的一种:

(1) WHERE expression [NOT] IN (subquery)

(2) WHERE expression comparison_operator [ANY | ALL]

(3)WHERE [NOT] EXISTS (subquery)

案例:

1、

使用子查询进行基于集合的测试

查询和王晓同地区的人,除了王晓以外

SELECT Cname,Address
FROM Table_Customer
WHERE Address   IN(
    SELECT Address
    FROM Table_Customer
    WHERE Cname=‘王晓’)
AND Cname!= ‘王晓’

2、

使用子查询进行比较测试

查询单价最高的商品的名称和单价

SELECT Goodname,SaleUnitPrice
FROM Table_Goods a
WHERE SaleUnitPrice=
(
    SELECT MAX(SaleUnitPrice)
    FROM Table_Goods
)

3、

使用子查询进行存在性测试

查询购买了单价高于2000元商品额顾客的会员卡号。

SELECT DISTINCT CardID
FROM Table_SaleBill
WHERE EXISTS(
    SELECT *
    FROM Table_SaleBillDetail
    WHERE SaleBillID=Table_SaleBill.SaleBillID
    AND UnitPrice>2000
)

第四节 其他形式的子查询

4.1.替代表达式的子查询

  在SELECT的选择列表中嵌入了一个只返回一个标量值的子查询。

实例:

SELECT Cname,Address,(
    SELECT COUNT(*)
    FROM Table_Customer b ON a.CardID=b. CardID
    WHERE CustomerID=‘C001’
)AS TotalTimes
FROM Table_Custmer
Where CustomerID=‘C001’

4.2.派生表

  • 也称为内联视图,是将子查询作为一个表处理,产生的新表为“派生表”。

实例:

查询至少买了G001和G002两种商品的顾客号和顾客名。

SELECT CustomerID,CName
FROM (
    SELECT *
    FROM Table_SaleBill a  JOIN Table_SaleBillDetail b
    ON  a.SaleBillID=b. SaleBillID
    WHERE  GoodsID=‘G001’
) AS T1 JOIN (
    SELECT *
    FROM Table_SaleBill a
    JOIN Table_SaleBillDetail b ON  a.SaleBillID=b. SaleBillID
    WHERE   GoodsID=‘G002’
) AS T2
ON T1.CardID=T2.CardID
JOIN Table_Customer c ON c.CardID=T1. CardID

第五节 其他一些查询功能

5.1.开窗函数

  • 在SQL Server 中,一组行被称为一个窗口。
  • 与聚合函数一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个值,开窗函数可以为每组返回多个值,因为开窗函数所执行聚合计算的行集组是窗口。
  • 与聚合函数不同的是,开窗函数在聚合函数后增加了一个OVER 关键字。
  • 开窗函数的调用格式为:
    函数名(列)OVER(选项)

    • OVER 关键字:表示把函数当成开窗函数而不是聚合函数。
    • SQL 标准允许将所有聚合函数用做开窗函数,使用OVER 关键字来区分这两种用法。

实例1:

将OVER字句与聚合函数结合使用

  设有课程表Course(Cno,CName,Credit,Semester)查询全部课程的Cno,CName,Semester, Credit信息及其该学期开设课程的总、最高、平均、最低Credit 。

SELECT Cno,CName,Semester ,Credit
SUM(Credit) OVER(PARTITION BY Semester) AS ‘Total’,
AVG(Credit) OVER(PARTITION BY Semester) AS ‘Avg’,
MIN(Credit) OVER(PARTITION BY Semester) AS ‘Min’,
MAX(Credit) OVER(PARTITION BY Semester) AS ‘Max’,
FROM Course

实例2:

将OVER子句与排名函数一起使用

  • 排名函数RANK()
RANK() OVER([<partition_by_clause>,…[n]]<order_by_clause>)
  • 注意: 排名函数具有不确定性 。

? 排名从1开始,不一定是连续整数。

SELECT OrderID, ProductID, OrderQty
    RANK() OVER(PARTITION BY OrderID ORDER  BY  OrderQty DESC )
    AS RANK
FROM OrderDetail
ORDER  BY OrderID 

其他排名函数

  • DENSE_RANK()

排名是连续整数

  • NTILE()

将有序分区中的行划分到指定数目的组中,编号从1开始,函数返回此行所属的组的编号。

  • ROW_NUMBER()

返回结果集中每个分区内的序列号,每个分区的第一行从1开始。

5.2.公用表表达式

  • 公用表表达式(CommonTableExpression,CTE):

将查询结果集指定一个临时名字,这些命名的结果集就是公用表表达式。

  • 格式:
WITH <common_table_expression>[,…n]
<common_table_expression>::=
Expression_name[(column_name [,…n])]
AS
(SELECT语句)

实例 :

定义一个统计每个会员购买商品总次数的CTE,并利用CTE查询会员卡号和购买商品的次数。

定义:

WITH BuyCount(CardID,Counts)
AS(SELECT CardID,Count(*)
   FROM Table_SaleBill
   GROUP BY CardID
  )

使用:

AS(
    SELECT CardID,Counts
    FROM BuyCount
    ORDER BY Counts
)

例题:

1、

1.设某数据库中有旅客表A(旅客编号,城市)和旅客表B(旅客编号,城市),现将所有旅客的数据存储这两张表中。请补全如下查询语句,使得该查询语句能查询所有旅客所在的全部的不重复的城市。
SELECT 城市 FROM 旅客表A
(  )
SELECT 城市 FROM 旅客表B
答案: UNION

2、

2.设有购买表(顾客号,商品号,购买时间)。现要查询顾客A与顾客B购买的相同商品。有下列查询语句:
Ⅰ.
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'A'
AND 商品号 IN (SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'B')
Ⅱ.
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'A'
        EXCEPT
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'B‘
Ⅲ.
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'A'
        INTERSECT
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'B'
Ⅳ.
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'A'
        UNION
SELECT 商品号 FROM  购买表 WHERE 顾客号 = 'B' 

上述语句中,能够实现该查询要求的是(  )。
A.仅Ⅰ和Ⅱ
B.仅Ⅰ和Ⅲ
C.仅Ⅰ和Ⅳ
D.仅Ⅲ
答案:B

3、

3.设有选课表(学号,课程号,成绩),现要统计每门课程的选课人数,并将结果保存到新表:选课情况表。下列语句中正确的是(      )。
A.
SELECT 课程号, COUNT(*) 选课人数 FROM 选课表 INTO 选课情况表GROUP BY 课程号
B.
SELECT 课程号, COUNT(*) 选课人数 INTO 选课情况表 FROM 选课表 GROUP BY 课程号
C.
SELECT 课程号, COUNT(*) FROM 选课表 INTO 选课情况表(课程号,选课人数)GROUP BY 课程号
D.
SELECT 课程号, COUNT(*) INTO 选课情况表(课程号, 选课人数)
FROM 选课表 GROUP BY 课程号
答案:B

4、

4.设某数据库中有学生表(学号,姓名,所在系)和选课表(学号,课程号,成绩)。现要查询没选课的学生姓名和所在系。下列语句中能够实现该查询要求的是(  )。
A.SELECT姓名,所在系FROM学生表a LEFT JOIN选课表b
ON a.学号=b.学号WHERE a.学号IS NULL
B.SELECT姓名,所在系FROM学生表a LEFT JOIN选课表b
ON a.学号=b.学号WHERE b.学号IS NULL
C.SELECT姓名,所在系FROM学生表a RIGHT JOIN选课表b
ON a.学号=b.学号WHERE a.学号IS NULL
D.SELECT姓名,所在系FROM学生表a RIGHT JOIN选课表b
ON a.学号=b.学号WHERE b.学号IS NULL
答案:B

5、

5.设在SQL Server2008中,用户U1在DB1数据库中创建了#Temp表。下列关于#Temp表的说法中,正确的是(  )。
A.在所有用户U1发起的连接中,都可以查询#Temp表数据
B.只有在创建#Temp表的连接中才可以查询#Temp表数据
C.在创建#Temp表的连接未断开时,DB1数据库的所有用户都可以查询#Temp表数据
D. 在创建#Temp表的连接断开时,DB1数据库的所有用户仍可以查询#Temp表数据
答案:B

6、

设在采用SQL Server 2008数据库的图书馆应用系统中有三个基本表,表结构如下所示,请用SQL语句完成下列两个查询:

BORROWER:

借书证号 姓名 系名 班级
12011106 蒋辉文 计算机系 12-1
12011107 王丽 计算机系 12-1
12012113 范园园 信息系 12-2
…… …… …… ……

LOANS:

借书证号 图书馆登记号 借书日期
12011106 T001001 2012.01.02
12012113 T001026 2013.02.06
…… …… ……

BOOKS:

索书号 书名 作者 图书登记号 出版社 价格
TP311.1 数据库系统 李明 T001001 科学 19.00
TP311.2 二级C语言 王珊 T001026 人民 32.00
…… …… …… …… …… ……

(1)检索至少借了5本书的同学的借书证号、姓名、系名和借书数。

(2)检索借书和王丽同学所借图书中的任意一本相同的学生姓名、系名、书名和借书日期。

1、

SELECT LOANS.借书证号,姓名,系名,COUNT(*)
AS 借书数量
FROM BORROWER,LOANS
WHERE BORROWER.借书证号=LOANS.借书证号
GROUP BY LOANS.借书证号
HAVING COUNT(*)>=5;

2、

SELECT 姓名,系名,书名,借书日期
FROM  BORROWER,LOANS , BOOKS
WHERE
 BORROWER.借书证号=LOANS.借书证号
 AND LOANS.图书登记号=BOOKS.图书登记号
AND 索书号 IN
(
    SELECT 索书号 FROM BORROWER,LOANS,BOOKS
    WHERE BORROW.借书证号=LOANS.借书证号
    AND LOANS.图书馆登记号=BOOKS.图书登记号
    AND 姓名="王丽"
)

原文地址:https://www.cnblogs.com/shaoyayu/p/12355331.html

时间: 2024-10-03 14:03:40

第七章、高级数据库查询的相关文章

oracle基本语句(第七章、数据库逻辑对象管理)

索引.实体化视图.簇.散列簇.序列.同义词 1.创建表 CREATE TABLE <表名>(<列名1> <数据类型>,--); CREATE GLOBAL TEMPORARY TABLE <表名>(<列名1> <数据类型>,--) ON COMMIT DELETE ROWS TABLESPACE <临时表空间名>;--创建事务级临时表,事务提交后删除临时表中数据 CREATE GLOBAL TEMPORARY TABLE

第七章 高级环境

第七章 高级环境 7.2 main函数 C程序总是从main函数开始执行的.main函数的原型是: int main(int argc, char *argv[]); 其中,argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组. 当内核执行C程序的时候(使用一个exec函数),在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址-- 这是由连接编辑器设置的,而连接编辑器则是由C编译器调用的.启动例程从内核取得命令行参数和环境变量值,然后为按上述

Java数据结构与算法(第七章高级排序1)

希尔排序 希尔排序是计算机科学家Donald L.Shell 而得名,他在1959年发现了希尔排序算法.希尔排序基于插入排序,但是增加了一个新的特性,大大提高了插入排序的执行效率. 插入排序:复制的次数太多 由于希尔排序是基于插入排序的,所以需要回顾下"插入排除".在插入排除执行的一半的时候,标记符左边这部分数据项都是排过序的(这些数据之间是有序的),而记右边的数据项没有排过序.这个算法取出标记符所指的数据项,把它存储在一个临时的变量.接着,从刚刚被移除的数据项的左边第一个单元看是,每

BPM-第七章-高级OOP特征

对象克隆,继承,接口,抽象类,命名空间 PHP5之后,将所有的对象都看成了引用. PHP不支持的高级OOP特征: 方法重载:不支持通过方法重载实现多态 操作都重载:不支持根据数据类型为操作符赋予新的含义 多重继承:不支持多重继承,支持实现多个接口 对象克隆 clone 关键字 destobj = clone sourceobj; __clone() 方法.在类中定义__clone()方法来调整对象的克隆行为. 继承 继承通过extends关键字实现 继承与延时绑定 ## 接口 原文地址:http

Java数据结构与算法(第七章高级排序2)

划    分 划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,是所有关键字小于特定值的数据项在另一组. package com.gaojipaixu.partition; public class Arraypar{     private long[] theArray;     private int nElems;          public Arraypar(int max){         theArray = new long[max];         nE

java MySQL数据库编程 第四章 高级查询(二)

第四章 高级查询(二) (1)通过在子查询中使用EXISTS子句,可以对子查询中的行是否存在进行检查.子查询可以出现在表达式出现的如何位置 (2)子查询语句可以嵌套在SQL语句中任何表达式出现的位置. 一.EXISTS子查询 1.使用EXISTS语句判断该数据库对象是否存在: DROP TABLE IF EXISTS temp; 2. EXISTS作为WHERE语句的子查询: SELECT .....FROM 表名 WHERE EXISTS(子查询); 3. EXISTS关键字后面的参数是一个任

【知识库】-数据库_MySQL之高级数据查询:去重复、组合查询、连接查询、虚拟表

简书作者:seay 文章出处: 关系数据库SQL之高级数据查询:去重复.组合查询.连接查询.虚拟表 回顾:[知识库]-数据库_MySQL之基本数据查询:子查询.分组查询.模糊查询 Learn [已经过测试校验] 一.去重复(DISTINCT) 二.组合查询 三.UNION(并集) 四.连接查询 五.虚拟表 一.去重复(DISTINCT) DISTINCT:用于返回唯一不同的值,主要是用于某一字段 语法 SELECT DISTINCT <列名>|* FROM <表名> 示例 -- 查

JavaScript高级程序设计(第3版)第七章读书笔记

第七章 函数表达式 1. 函数声明有一个重要特征 ,函数声明提升.即在执行代码之前会先读取函数声明,意味着可以把函数声明放在调用它的语句后面. 2. 使用arguments.callee实现对函数的递归调用.但在严格模式下,不能通过脚本访问arguments.callee,但可以使用命名函数表达式来达成相同的效果. 3. 闭包是指有权访问另一个函数作用域中的变量的函数.创建闭包的常用方式,就是在一个函数内部创建另一个函数. 4. 由于闭包会携带包含它的函数的作用域,因此会比其他函数占更多的内存.

C#高级编程第11版 - 第七章

导航 C# 全版本特性一览 全书目录 第七章 Arrays 7.1 相同类型的多个对象 151 7.2 简单数组 152 7.2.1 数组的声明 152 7.2.2 数组的初始化 152 7.2.3 访问数组元素 153 7.2.4 使用引用类型 153 7.3 多维数组 154 7.4 锯齿数组 155 7.5 Array 类 156 7.5.1 创建数组 156 7.5.2 复制数组 156 7.5.3 排序 157 7.6 数组作为参数 159 7.7 数组协变 159 7.8 枚举 16