2011-07-26 72 views
1

我有一個包含2列,Ex_Id和Term_Id,都是int類型的表。我的表格將會有許多期限ID用於一個練習ID。查詢以基於此多個條件從表中選擇值列表

 Table would look like this: 
     Ex_Id Term_Id 
     1  2 
     1  3 
     1  4 
     1  5 
     2  2 
     3  2 
     3  4 

等。獲取Ex_Id列表是主要要求。我的功能就是這樣。

List<int> Get_ExId_List(List<int> lst_TermId) 
{ 
    // return a list of Ex_Id <int> 
} 

也就是說,我將傳遞一個Term Ids列表,並且需要獲得一個符合某些條件的Exercise Ids列表。的標準來選擇可與此僞代碼來更好地解釋:SELECT such Ex_Ids FROM table Exercise_Term WHERE Ex_Id has all the corresponding Term_Ids in the lst_TermId

對於例如,從樣品臺我的上方,

List<int> Get_ExId_List([2]) 
{ 
    // return [1,2,3] 
} 

List<int> Get_ExId_List([2,4]) 
{ 
    // return [1,3] 
} 

List<int> Get_ExId_List([2,3,4]) 
{ 
    // return [1] 
} 

查詢部分是我的混亂。在這種情況下查詢會是什麼樣的?休息我可以管理。希望的問題很明顯。謝謝..

回答

2
SELECT Ex_ID 
FROM TableName 
WHERE Term_ID IN (?, ?, ?)    --- (2, 3, 4) 
GROUP BY Ex_ID 
HAVING COUNT(DISTINCT Term_ID) = 3  --- number of terms in the above list 

如果組合(Ex_ID, Term_ID)是在表中唯一的,你可以用COUNT(*)

這是一個關係劃分問題更換COUNT(DISTINCT Term_ID)。 「標準」 的解決方案將使用兩個否定(NOT EXISTS):

SELECT DISTINCT Ex_ID 
FROM TableName e 
WHERE NOT EXISTS 
     (SELECT * 
      FROM TableName t 
      WHERE t.Term_ID IN (?, ?, ?)   --- the list of terms 
      AND NOT EXISTS 
        (SELECT * 
        FROM TableName a 
        WHERE a.Term_ID = t.Term_ID 
         AND a.Ex_ID = e.Ex_ID 
       ) 
     ) 

或更好的在您的情況:

SELECT DISTINCT Ex_ID 
FROM TableName e 
WHERE NOT EXISTS 
     (SELECT * 
      FROM 
      (SELECT ? AS Term_ID 
      UNION 
       SELECT ? 
      UNION 
       SELECT ? 
      ) AS t 
      WHERE NOT EXISTS 
        (SELECT * 
        FROM TableName a 
        WHERE a.Term_ID = t.Term_ID 
         AND a.Ex_ID = e.Ex_ID 
       ) 
     ) 

+0

給我一些時間來測試這個。謝謝。這個查詢的確很棘手 – nawfal

1

您可以使用LINQ。獲取整個表到某種類型的IEnumerable中,然後使用LINQ。 下面是一個例子:

static IEnumerable<int> Get_ExId_List(ICollection<int> lst_TermId) 
{ 
    //this is just for the example - get the real data instead 
    var data = new[] { 
     new { Ex_Id = 1, Term_Id = 2}, 
     new { Ex_Id = 1, Term_Id = 3}, 
     new { Ex_Id = 1, Term_Id = 4}, 
     new { Ex_Id = 1, Term_Id = 5}, 
     new { Ex_Id = 2, Term_Id = 2}, 
     new { Ex_Id = 3, Term_Id = 2}, 
     new { Ex_Id = 3, Term_Id = 4}, 
    }; 

    return data 
     .Where(row => lst_TermId.Contains(row.Term_Id)) 
     .GroupBy(row => row.Ex_Id) 
     .Where(group => group.Count() == lst_TermId.Count()) 
     .Select(group => group.Key); 
} 

static void Main(string[] args) 
{ 
    HashSet<int> lst_TermId = new HashSet<int>(); 
    lst_TermId.Add(2); 

    Console.WriteLine(); 
    var result = Get_ExId_List(lst_TermId); 
    foreach (var exid in result) 
     Console.WriteLine(exid); 

    lst_TermId.Add(4); 

    Console.WriteLine(); 
    result = Get_ExId_List(lst_TermId); 
    foreach (var exid in result) 
     Console.WriteLine(exid); 

    lst_TermId.Add(3); 

    Console.WriteLine(); 
    result = Get_ExId_List(lst_TermId); 
    foreach (var exid in result) 
     Console.WriteLine(exid); 
} 

請注意,您會得到更好的性能,如果你的lst_TermId是HashSet<int>,因爲contains方法將O(1)而不是O(n)

+0

我使用.Net 2.0。這沒有正確的工作。 – nawfal

+0

噢,你需要3.5或以上的LINQ ... –

+0

但無論如何這對我很有用,考慮到我在家使用.Net 4 :) – nawfal

相關問題