您的位置:首页 > 产品设计 > UI/UE

SqlServer 2005 T-SQL Query 学习笔记(7)

2010-02-24 11:47 656 查看
介绍2个关键字的用法:EXCEPT,INTERSECT.

EXCEPT

例子如下,

TABLE1:1,2,3

TABLE2:3,4,5

TABLE1EXCEPTTABLE2结果为1,2

TABLE2EXCEPTTABLE1结果为4,5

原始实现(非关键字实现):

SELECTCountry,Region,City
--注意:这里子查询里使用DISTINCT去除了重复。
FROM(SELECTDISTINCT'E'ASSource,Country,Region,City
FROMdbo.Employees
UNIONALL
SELECTDISTINCT'C',Country,Region,City
FROMdbo.Customers)ASUA
GROUPBYCountry,Region,City
HAVINGCOUNT(*)=1ANDMAX(Source)='E';


关键字实现:

SELECTCountry,Region,CityFROMdbo.Employees
EXCEPT
SELECTCountry,Region,CityFROMdbo.Customers


EXCEPTALL

例子如下:

TABLE1:1,1,2,3

TABLE2:1,3,3

TABLE1EXCEPTALLTABLE2结果为1,2

TABLE2EXCEPTALLTABLE1结果为3

注意:EXCEPTALL其实是增加了有可能出现重复的情况,并把多余重复的数据也进行归纳。

微软没有EXCEPTALL的关键字,可能这种情况在日常使用中比较的少用,所以就没有特定吧。

代码实现:

SELECTCountry,Region,City
--统计相同country,region,city中,E,C的个数
FROM(SELECTCountry,Region,City,
MAX(CASEWHENSource='E'THENCntELSE0END)ECnt,
MAX(CASEWHENSource='C'THENCntELSE0END)CCnt
--查找E,C相同country,region,city的行数。
FROM(SELECT'E'ASSource,
Country,Region,City,COUNT(*)ASCnt
FROMdbo.Employees
GROUPBYCountry,Region,City

UNIONALL

SELECT'C',Country,Region,City,COUNT(*)
FROMdbo.Customers
GROUPBYCountry,Region,City)ASUA
GROUPBYCountry,Region,City)ASP
JOINdbo.Nums
ONn<=ECnt-CCnt;


更巧妙的方法,使用ROW_NUMBER()函数:

WITHEXCEPT_ALL
AS
(
SELECT
ROW_NUMBER()
OVER(PARTITIONBYCountry,Region,City
ORDERBYCountry,Region,City)ASrn,
Country,Region,City
FROMdbo.Employees

EXCEPT

SELECT
ROW_NUMBER()
OVER(PARTITIONBYCountry,Region,City
ORDERBYCountry,Region,City)ASrn,
Country,Region,City
FROMdbo.Customers
)
SELECTCountry,Region,City
FROMEXCEPT_ALL;


方法很巧妙,即是把重复的数据按1,2,3…N编上序号,把重复数据变成不重复的独立数据,然后使用EXCEPT.

INTERSECT

例子如下,

TABLE1:1,2,3

TABLE2:3,4,5

TABLE1INTERSECTTABLE2结果为3

TABLE2INTERSECTTABLE1结果为3

原始实现(非关键字):

SELECTCountry,Region,City
--注意:这里子查询已经去除了重复
FROM(SELECTDISTINCTCountry,Region,CityFROMdbo.Employees
UNIONALL
SELECTDISTINCTCountry,Region,CityFROMdbo.Customers)ASUA
GROUPBYCountry,Region,City
HAVINGCOUNT(*)=2;


关键字实现:

SELECTCountry,Region,CityFROMdbo.Employees
INTERSECT
SELECTCountry,Region,CityFROMdbo.Customers;


INTERSECTALL

例子如下:

TABLE1:1,1,2,2

TABLE2:1,2,2,3

TABLE1INTERSECTTABLE2结果为1,2,2

TABLE2INTERSECTTABLE1结果为1,2,2

此处和EXCEPT一样,增加了重复数据的情况。

代码实现:

SELECTCountry,Region,City
FROM(SELECTCountry,Region,City,MIN(Cnt)ASMinCnt
FROM(SELECTCountry,Region,City,COUNT(*)ASCnt
FROMdbo.Employees
GROUPBYCountry,Region,City

UNIONALL

SELECTCountry,Region,City,COUNT(*)
FROMdbo.Customers
GROUPBYCountry,Region,City)ASUA
GROUPBYCountry,Region,City
HAVINGCOUNT(*)>1)ASD
JOINdbo.Nums
ONn<=MinCnt;


更简单的方法,使用ROW_NUMBER()函数:

WITHINTERSECT_ALL
AS
(
SELECT
ROW_NUMBER()
OVER(PARTITIONBYCountry,Region,City
ORDERBYCountry,Region,City)ASrn,
Country,Region,City
FROMdbo.Employees

INTERSECT

SELECT
ROW_NUMBER()
OVER(PARTITIONBYCountry,Region,City
ORDERBYCountry,Region,City)ASrn,
Country,Region,City
FROMdbo.Customers
)
SELECTCountry,Region,City
FROMINTERSECT_ALL;


和EXCEPTALL一样,也是把重复数据独立成不重复数据。

集合运算优先权

INTERSECT是具有最高优先级的:

SELECTCountry,Region,CityFROMdbo.Suppliers
EXCEPT
SELECTCountry,Region,CityFROMdbo.Employees
--实际上是INTERSECT最先执行。
INTERSECT
SELECTCountry,Region,CityFROMdbo.Customers;

使用()可以改变默认的顺序:

(SELECTCountry,Region,CityFROMdbo.Suppliers
EXCEPT
SELECTCountry,Region,CityFROMdbo.Employees)
INTERSECT
SELECTCountry,Region,CityFROMdbo.Customers;


Technorati标签:t-sql.sql2005,query
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: