给定集与其他集之间的距离 - sql server 2005

时间:2012-02-03 08:38:24

标签: sql sql-server sql-server-2005 tsql

我有一个包含项目和类别ID的表格:

create table SomeTable (
    ItemId int,
    CategoryId int
)

鉴于某些类别ID(集合X),我想确定至少共享一个类别ID的所有项目ID以及每个项目ID的一些统计信息:

A - 项目ID的类别ID数量不在集合x
中 B - 项目ID和集合x之间共享的类别ID的数量 C - 集合x中的类别ID的数量,但与项目ID无关

我编写了一些tsql代码,它涉及交叉连接和几个ctes以及左连接。它有效,但相当慢。

我相信某人肯定遇到过类似的问题。我会提供代码,但上面的描述是简化的。感谢。

2 个答案:

答案 0 :(得分:1)

以下是一些想法。 (我不知道他们将如何将性能与你已经拥有的东西进行比较。留给你进行基准测试。)

set nocount on;

-- create a sample table
declare @T table ( ItemId int identity(1,1), CategoryId int );
insert @T values ( 100 );
insert @T values ( 100 );
insert @T values ( 100 );
insert @T values ( 100 );
insert @T values ( 100 );
insert @T values ( 200 );
insert @T values ( 200 );
insert @T values ( 300 );
insert @T values ( 300 );
insert @T values ( 300 );
insert @T values ( 300 );
insert @T values ( 500 );
insert @T values ( 500 );
insert @T values ( 500 );
insert @T values ( 600 );
insert @T values ( 700 );
insert @T values ( 800 );
insert @T values ( 800 );
insert @T values ( 800 );
insert @T values ( 900 );


-- grab some CategoryIDs to work with
declare @X table ( CategoryId int );
insert @X
    select CategoryID=200 union
    select CategoryID=400 union
    select CategoryID=600 union
    select CategoryID=800 


-- A. Number of category ids of item id that are not in set x
select distinct t.CategoryID from @T t
where not exists(select 1 from @X x where t.CategoryID = x.CategoryID)

-- or, using the set difference operator
select CategoryID from @T
except
select CategoryID from @X


-- B. Number of category ids shared between item id and set x
select distinct x.CategoryID from @X x
join @T t on t.CategoryID = x.CategoryID;

-- or, using set intersection
select CategoryID from @T
intersect
select CategoryID from @X


-- C. Number of category ids in set x but which are not associated with item id 
select distinct x.CategoryID from @X x
where not exists(select 1 from @T t where t.CategoryID = x.CategoryID)

-- or, using the set difference operator
select CategoryID from @X
except
select CategoryID from @T

答案 1 :(得分:1)

CTE的问题是它们在每次引用时都会运行,并且没有约束。将Set X加载到ID为主键的临时表中。然后对临时运行相同的连接,你应该看到大的性能提升。当连接基于主键时,SQL会做得更好。