选择值组合

时间:2014-01-11 17:38:49

标签: sql

我有一个包含3列的表格:

fileTagId: autoincrement, primary
fileId
tagId

多个标签(tagId)可以与同一个文件(fileId)相关联,如下所示:

fileTagId | fileId | tagId
1         |1       | 4
2         |1       | 9
3         |1       | 12
4         |1       | 17
5         |2       | 4
6         |2       | 9
7         |2       | 19
8         |3       | 4
9         |3       | 7
10        |4       | 4
11        |5       | 32
12        |5       | 47
13        |5       | 49
14        |5       | 63 

我希望选择具有特定标签组合的所有文件(fileId)(tagId),例如所有带有标签4和9的文件,它应该在上表中返回以下内容:

1
2

因为只有文件编号1和2标记为4和9作为标记

2 个答案:

答案 0 :(得分:2)

我发现处理这些查询的最常用方法是使用聚合having子句:

select fileid
from t
group by fileid
having sum(case when tagid = 4 then 1 else 0 end) > 0 and
       sum(case when tagid = 9 then 1 else 0 end) > 0;

having子句中的每个条件都计算与其中一个标记匹配的行数。您至少需要其中一个,因此> 0

我喜欢这种方法的原因是因为添加新条件很容易。假设您想要4和9而不是6

having sum(case when tagid = 4 then 1 else 0 end) > 0 and
       sum(case when tagid = 9 then 1 else 0 end) > 0 and
       sum(case when tagid = 6 then 1 else 0 end) = 0;

答案 1 :(得分:1)

您可以使用STUFF或PIVOT完成此操作:

SELECT DISTINCT FileId
FROM 
(
    SELECT FileId,
            STUFF((SELECT ',' + CAST(TagId as varchar)
                    FROM #FileTag b
                    WHERE b.FileId =  a.fileId
                    ORDER BY TagId
                    FOR XML PATH(''))
                , 1, 1, '') AS NameList
    FROM #fileTag a
) t 
WHERE t.NameList like '%4,%9,%'

或PIVOT

SELECT DISTINCT FileId 
FROM 
(
    SELECT * 
    FROM 
        (
            SELECT DISTINCT FileId, TagId 
            FROM #FileTag 
        ) a 
        PIVOT (MAX(TagId) FOR TagId IN ([4], [9])) p
) t
where [4]+[9] IS NOT NULL