我有一张桌子喜欢这个;
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
答案 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