T-SQL选择映射列上的完全匹配

时间:2017-11-23 19:26:19

标签: sql sql-server tsql

我有两张桌子:

表A

Id      Feature 
-----------------
1             a          
2             b
3             c
4             d                

表B

Id          AId
-----------------
1             1
1             3
2             1
3             1
3             3
3             4
4             1
4             3            

所以你可以把表B看作

  • Id 1具有以下功能 - a,c
  • Id 2具有以下功能 -
  • Id 3具有以下功能 - a,c,d
  • Id 4具有以下功能 - a,c

我想获得表B中具有特定功能的所有ID

因此对于[a,c]我想回[1,4]

我能想到正确做法的唯一方法是为表B中的每个id获取csv列表,并找到与我的查询完全匹配的列表。

有没有人有更好的方法?我的方式并没有利用表格上的索引,我认为随着表格变大,速度会慢得多。

2 个答案:

答案 0 :(得分:0)

不,您不需要将值连接在一起。 group byhaving就足够了:

select b.id
from b join
     a
     on b.aid = a.id
group by b.id
having sum(case when a.feature = 'a' then 1 else 0 end) > 0 and  -- has "a"
       sum(case when a.feature = 'c' then 1 else 0 end) > 0 and  -- has "c"
       sum(case when a.feature not in ('a', 'c') then 1 else 0 end) = 0  -- has nothing else

答案 1 :(得分:0)

所以这就是我现在所解决的问题。它在sp中使用,它有一个将csv行转换为CSVToTable表的函数。

declare @features nvarchar(max), @fcount int;

--using a csv list of features as input to the query
set @features = 'a,b';

--just to row count of the features
set @fcount = (select count(*) from [CSVToTable](@features))

SELECT mat.Id from 

(
    SELECT Id from B b1
    JOIN A a1 on b1.AId = a1.Id
    JOIN [CSVToTable](@features) f on f.Id = a1.Feature
    GROUP BY count(b1.Id)
    HAVING COUNT(b1.Id) = @fcount) mat
JOIN (
    SELECT Id from B b2
    GROUP BY count(b1.Id)
    HAVING COUNT(b1.Id) = @fcount) mat
) all1 on all1.Id = mat.Id

所以它不是那么容易阅读,但我按第一个表AND INNER JOIN分组我创建的功能表,其中包含一个has子句,它具有完全相同的功能。对此的问题在于它不排除具有额外功能的ID,例如:我想要a,b但我也得到具有a,b,c的id。所以要修复这个I内连接,表B中所有具有相同数量功能的记录。