论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Sql Server教程
Tag:注入,存储过程,分页,安全,优化,加密,索引,日志,压缩,base64,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,触发器,socket,安装,sqlserver2000,sqlserver2005,sqlserver2008,视频教程

集合成员和关系

文章类别:Sql Server | 发表日期:2008-10-5 21:35:29

集合之间的关系绿色c hinaip ower. comaFrwyXt

为了介绍我在本文中讨论的问题,首先我们来回顾一下集合论中表示集合之间关系的几个概念。我使用这些概念来为本文所讨论的问题定义条件。我用大写字母指定集合名称,用编号的小写字母指定集合成员,用里面包含集合成员的花括号指定集合本身。绿色c hinaip ower. comaFrwyXt

集合论描述了集合之间可以存在的某些关系:绿色c hinaip ower. comaFrwyXt

集合 U 等于集合 V,条件是:U 的所有成员都存在于 V 中,并且 V 的所有成员都存在于 U 中 - 例如,U = {u1, u2, u3},V = {u1, u2, u3}。 绿色c hinaip ower. comaFrwyXt

如果 U 的所有成员都存在于 V 中,则 U 是 V 的子集。当 U 等于 V 时,U 是 V 的子集,V 也是 U 的子集。绿色c hinaip ower. comaFrwyXt

当 U 是 V 的子集,但 V 不是 U 的子集时,U 是 V 的真子集 - 例如,U = {u1, u2, u3},V = {u1, u2, u3, u4}。绿色c hinaip ower. comaFrwyXt

我在本文中讨论的任务涉及到确定与另一个项组有某种关系的项组,也就是集合。我们先来看一个提出问题的示例。绿色c hinaip ower. comaFrwyXt

Orders OrderDetails 方案绿色c hinaip ower. comaFrwyXt

我使用的方案涉及到作为示例的 Orders 表和 OrderDetails 表,您可以运行 清单 1显示的脚本在 tempdb 中创建并填充这两个表。这些表只包括了与本文讨论内容相关的列 - 即,Orders 中的 orderid 列和 OrderDetails 中的 orderid 和 productid 列。Orders 表中的每个订单在 OrderDetails 表中可能不存在相关行;或存在一个或多个相关行,每一行都包含不同的产品。就其本质来说,每个定单都是实体的一个实例,但在本文中,我所指的定单是属于定单的一组详细信息。绿色c hinaip ower. comaFrwyXt

应用程序用户输入一组代表新定单的产品,您的代码将它们存储在 #ProdList 临时表中:绿色c hinaip ower. comaFrwyXt

CREATE TABLE #ProdList(productid int NOT NULL PRIMARY KEY)

INSERT INTO #ProdList VALUES(2)

INSERT INTO #ProdList VALUES(3)

INSERT INTO #ProdList VALUES(4)

您从市场营销部门接受了几个任务,要求您确定新定单和现有定单之间的不同关系。这些关系对于市场营销部门可能很重要,营销部门会据此确定采购模式,考虑某些产品组的折扣,等等。绿色c hinaip ower. comaFrwyXt

任务 1P O 的子集。您的第一个任务是确定包含 #ProdList 中的所有产品的定单。用集合术语来说,如果 O 代表构成定单的定单详细信息的集合,P 代表 #ProdList 中的产品的集合,您就要查找满足“P 是 O 的子集”这一条件的定单。您的查询应该返回定单 A 和 B。绿色c hinaip ower. comaFrwyXt

下面的查询为您提供了该任务的解决方案:绿色c hinaip ower. comaFrwyXt

SELECT orderid

FROM OrderDetails

WHERE productid IN(SELECT productid FROM #ProdList)

GROUP BY orderid

HAVING COUNT(*) = (SELECT COUNT(*) FROM #ProdList)

此代码查询 OrderDetails 表,筛选出只包含存在于 #ProdList 中的产品的行。该查询按 orderid 对结果进行分组,然后筛选产品数与 #ProdList 表中的产品数相同的组。该查询只返回包含 #ProdList 中的所有产品的定单。绿色c hinaip ower. comaFrwyXt

任务 2P 等于 O您的第二个任务是确定包含 #ProdList 中的所有产品但不包含其他产品的定单。用集合术语来说,您要查找满足“P 等于 O”这一条件的订单。在前面的查询中,WHERE 子句去除了那些包含 #ProdList 中不存在的产品的行,所以该查询未考虑那些行。但这一次,您需要考虑所有行。要解决此问题,您可以先编写一个返回 OrderDetails 中的所有行的查询,向结果追加到一个名为 inlist 的列中;对于 #ProdList 中存在的产品,该列的取值为 1,对于不包含的产品,该列的取值为 -1:绿色c hinaip ower. comaFrwyXt

SELECT *,

CASE

WHEN productid IN(SELECT

productid FROM #ProdList)

THEN 1

ELSE -1

END AS inlist

FROM OrderDetails

图 1显示了此查询的结果。绿色c hinaip ower. comaFrwyXt

清单 2中的代码由前面的查询形成一个派生表,按 orderid 对该表的行进行分组,只返回 inlist 值的总和等于 #ProdList 中的产品数的那些组。要使 HAVING 子句中的条件为真,定单必须包含 #ProdList 中的所有产品并且不包含其他产品,而这正是请求所指定的。结果中应该只包含定单 B。绿色c hinaip ower. comaFrwyXt

任务 3P O 的真子集。任务 3 要求您确定包含 #ProdList 中的所有产品和至少一种其他产品的定单。用集合术语来说,您需要满足“P 是 O 的真子集”这一条件的所有定单。您可以使用类似于前面查询中的方法,即,使用一个包含所有定单详细信息和名为 inlist 的附加列的派生表。这一次,对于 #ProdList 中存在的产品,使得 inlist 列的取值为 1,对于不存在的产品,使得该列的取值为 NULL;如 清单 3所示。绿色c hinaip ower. comaFrwyXt

在 HAVING 子句中,通过将非 Null 的 inlist 值的数目 - COUNT(inlist) - 与 #ProdList 中的产品数目进行比较,确保查询只返回包含 #ProdList 中的所有产品的组。通过检查该组中的总行数是否大于非 Null 的 inlist 值的数目,您可以确保返回的定单至少包含一种不存在于 #ProdList 中的产品。结果中应该只包含定单 A。绿色c hinaip ower. comaFrwyXt

任务 4O P 的子集。任务 4 调换了 P 和 O 的角色。您需要返回其所有产品都在 #ProdList 中的订单。用集合术语来说,您需要返回满足“O 是 P 的子集”这一条件的所有定单。为了获得此结果,可以执行 OrderDetails 和 #ProdList 之间的左外部联接。这种联接的结果会返回所有定单详细信息,无论 #ProdList 中是否存在匹配(#ProdList 中的列的 NULL 表示不匹配)都是如此。您要查找的定单就是那些包含的所有定单详细信息在 #ProdList 中存在匹配的定单 - 也就是说,在 #ProdList 的列中没有 NULL 的定单。确定这些定单的一种简单方法是,按 orderid 对联接的结果进行分组,使用 HAVING 子句来检查该组中所有行的计数是否等于 #ProdList 中非 Null 的 productid 值的计数。清单 4 显示的此查询应该返回定单 B、C 和 D。绿色c hinaip ower. comaFrwyXt

任务 5O P 的真子集。最后一个任务是确定所有产品均存在于 #ProdList 中的定单,同时 #ProdList 至少包含一种另外的产品。用集合术语来说,您要查找满足“O 是 P 的真子集”这一条件的定单。您需要在前面的查询中添加一点内容,修改后的查询将返回作为 #ProdList 的子集(不一定是真子集)的定单。如 清单 5的最后一行所示,您向 HAVING 子句添加了一个表达式,以确保定单中的产品数目小于 #ProdList 中的产品数目。结果中应该包含定单 C 和 D。绿色c hinaip ower. comaFrwyXt

 绿色c hinaip ower. comaFrwyXt

上一篇:{技巧}查询开放内容 人气:2008
下一篇:{技巧}数据访问技术的演变 人气:1666
视频教程列表
文章教程搜索
 
Sql Server推荐教程
Sql Server热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058