2014-01-11 2 views
0

У меня есть таблица с 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 

I хотите выбрать все файлы (fileId) с определенной комбинацией тегов (tagId), например, все файлы с тегами 4 и 9, и в приведенной выше таблице должны быть указаны следующие значения:

1 
2 

, как только номер файла 1 и 2 имеют ОБА 4 и 9 в качестве тегов

ответ

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; 
+0

Thanx флэш Гордоном Упс SQL ГОРДОН;) – timmaktu

1

Вы можете сделать это с помощью STUFF или шарнирные так:

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,%' 

или шарнирные

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 
+0

это может быть правильно, но слишком сложно для меня noob, thanx в любом случае – timmaktu

Смежные вопросы