簡體   English   中英

查詢以基於此多個條件從表中選擇值列表

[英]Query to select a list of values from a table based on this multiple criteria

我有一個包含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>
}

也就是說,我將傳遞術語ID的列表,並且需要獲取與某些條件匹配的演習ID的列表。 使用此偽代碼可以更好地解釋選擇的標准: 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]
}

查詢部分是我的困惑。 在這種情況下查詢將是什么樣的? 我可以管理的休息。 希望問題很清楚。 謝謝..

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(DISTINCT Term_ID)替換為COUNT(*)

這是一個關系划分問題。 “標准”解決方案將使用兩個否定詞(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
                  )
        ) 

您可以使用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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM