2013-11-01 72 views
1

場景:噸-SQL子查詢組

  • 模塊1具有標籤AB
  • 模塊2具有標籤AB
  • 模塊3具有標籤A
  • 模塊4具有標籤B
  • 模塊5具有標籤ABC

在表:

ModuleId TagId 
1   A 
1   B 
2   A 
2   B 
3   A 
4   B 
5   A 
5   B 
5   C 

條件:

  • 我有標籤識別前的列表:列出<>標記列表= {A,B}
  • 我想所有這些TagIds下相同的moduleId下降,比TagIds列表其他(即tagList)。從而導致它應該返回標籤識別C.

TSQL語句 -

select TagId 
from Table 
where ModuleId in (
    select ModuleId 
    from Table 
    where TagId in(A,B) 
    group by ModuleId having count(ModuleId) = 2) 
and TagId not in (A,B) 

LINQ語句 -

List<int?> temp = (from t1 in context.Table 
          where tagList.Contains(t1.TagId) 
          group t1 by t1.ModuleId into grouped 
          where grouped.Count() == tagList.Count() 
          select grouped.Key).ToList(); 

      var result = (from t2 in context.Table 
        where temp.Contains(t2.ModuleId) && !tagList.Contains(t2.TagId) 
        select t2).Distinct().ToList(); 

所以我是 -

  • 問題應該是什麼這種情況下的最佳方法?
  • 如果有更好的方法,那麼LINQ方法的語法是什麼?

在此先感謝。

+0

爲了說明一下,您希望表格中的項目屬於您的tagList中包含具有* all *標籤的項目的模塊,但是它們本身沒有與tagList中的標籤相同的標籤? – StriplingWarrior

回答

0

這是你的要求更簡單的翻譯,但它產生的SQL爲您的標記列表變大變得更爲複雜:

// Get items from the table 
from t in context.Table 
// ... that belong to modules 
group t by t.ModuleId into moduleTags 
// ... that have items for all the tags in the tagList 
where tagList.All(tagId => moduleTags.Any(t => t.TagId == tagId)) 
from t in moduleTags 
// ... but which themselves don't have the same tags as in the tagList. 
where !tagList.Contains(t.TagId) 
select t; 

從開始,但充分利用您「計數==計數」的把戲,這裏有一個非常簡單的實現,應該更好的規模:

// Get items from the table 
from t in context.Table 
// ... that belong to modules 
group t by t.ModuleId into moduleTags 
// ... that have items for all the tags in the tagList 
where moduleTags.Count(t => tagList.Contains(t.TagId)) == tagList.Count() 
from t in moduleTags 
// ... but which themselves don't have the same tags as in the tagList. 
where !tagList.Contains(t.TagId) 
select t; 

後者的實現,像你原來的SQL,假定兩個表格條目和您的標記列表只有獨特的條目。否則,Counts將關閉。

+0

Brilliant ..我會去第二次LINQ聲明..謝謝 – Hiral