使用Intersect在SQL中的某些值

时间:2016-11-23 07:35:24

标签: sql tsql

我有一张桌子喜欢这个;

 PROPERTY1  |  PROPERTY2 
 -----------+-------------
  A         | 1
  A         | 2
  A         | 3
  B         | 2
  B         | 4
  B         | 6
  C         | 5

我只想看到结果的交集。

实施例;我想看到" 2"结果为A和B的交点。 但是如果我使用A,B和C作为条件,查询必须返回空。

我基本上怎么做?

这两个解决方案正在运行,但如果我使用了太多的property1值(在where命令中),我会得到大量的查询。有一个简单的解决方案吗?

SELECT PROPERTY2
FROM TABLE1 AS X WHERE X.PROPERTY1 IN ('A')
INTERSECT
SELECT PROPERTY2
FROM TABLE1 AS T WHERE T.PROPERTY1 IN ('B')

并且

SELECT DISTINCT PROPERTY2 FROM TABLE1 WITH (NOLOCK) 
WHERE 
PROPERTY1=N'A' 
AND OZELLIK2 IN (SELECT DISTINCT PROPERTY2 FROM TABLE1 WITH (NOLOCK) WHERE PROPERTY1 IN ('B') )
ORDER BY PROPERTY2 ASC

3 个答案:

答案 0 :(得分:1)

试试吧。喜欢“自我加入”

 CREATE TABLE #TMP( PROP_1 VARCHAR(1), PROP_2 INT)

INSERT INTO #TMP 
SELECT 'A', 1
INSERT INTO #TMP 
SELECT 'A', 2
INSERT INTO #TMP 
SELECT 'A', 3
INSERT INTO #TMP 
SELECT 'B', 2
INSERT INTO #TMP 
SELECT 'B', 4
INSERT INTO #TMP 
SELECT 'C', 6


DECLARE @I VARCHAR(5)
DECLARE @SQL  NVARCHAR(MAX) = ''
declare curs SCROLL cursor for 
select distinct prop_1 from #TMP where prop_1 in ('A','B','C') 
OPEN curs;
FETCH NEXT FROM curs INTO @I;
WHILE @@FETCH_STATUS=0
    BEGIN
          SET @SQL += ' SELECT PROP_2 FROM #TMP WHERE PROP_1 = ''' + @I + '''' ;    

    FETCH NEXT FROM curs INTO @I;

    if @@FETCH_STATUS=0
    begin
        set @SQL +=  ' INTERSECT';
    end

    END
CLOSE curs   
DEALLOCATE curs

PRINT @SQL

exec sp_executesql @SQL

DROP TABLE #TMP

答案 1 :(得分:1)

根据您的评论"示例;我想看到" 2"结果作为A和B的交集。但是如果我使用A,B和C作为条件,查询必须返回空。",看起来你想要/需要的操作是关系划分的操作。

只有间接的方式在SQL中编写操作(并且有很多方法没有任何客观标准来决定哪个是"更好")但通常涉及以下计算阶段:

(1)确定您的一组PROPERTY1值({A,B}或{A,B,C})
(2)确定候选人" PROPERTY2值(SELECT PROPERTY2 FROM your_tbl JOIN tbl_from_1 ON ... .PROPERTY1 = ... .PROPERTY1
(3)构建"最大"表格加入(1)和(2)
(4)从(3)中减去your_tbl,这将为您提供所有未出现在your_tbl中的PROP1 / PROP2组合。
(5)SELECT PROPERTY2 FROM(4),它为您提供了所有PROPERTY2值,这些值在-tbl中没有出现在(1)中涉及的所有PROPERTY1值中 (6)从(2)中减去(5),这给出了在(1)中涉及的所有PROPERTY1值的your_tbl中出现的所有PROPERTY2值。

关于关系划分的完整故事在这里太长了,无法适应这个空间,如果你想了解更多,那么谷歌就是你的朋友。

答案 2 :(得分:1)

这可能是一种方法 - 传递表值param并将其连接到数据 - 其中给定属性的结果计数与传入的值的计数相同,您有一个相交。这适用于这个点头的例子,我不能100%肯定它不会被绊倒。

如果您因任何原因无法使用TVP,您可以传入一个csv字符串并将其拆分。

create table Prop
(
    property1 char(1),
    property2 int
)

insert into Prop values('A',1),('A',2),('A',3),('B',2),('B',4),('B',6),('C',5)

create type Property1TableType as table (property1 char(1))
go

create procedure usp_GetIntersect
    @params Property1TableType readonly
as

-- count the number of distinct params
declare @c int
select @c = count(distinct property1) from @params

-- find where the number of distinct values after joining is the same as the number of distinct params
select distinct property2
from Prop
inner join @params tt on Prop.property1 = tt.property1
group by property2
having count(distinct tt.property1) = @c

go

-- run our procedure
-- first create the parameter table to pass
declare @p Property1TableType
insert into @p values('A'),('B')

exec usp_GetIntersect @p

-- now also insert C and run again
insert into @p values('C')

exec usp_GetIntersect @p