查询以根据多个条件从表中选择值列表

发布于 2024-11-26 04:17:47 字数 871 浏览 7 评论 0原文

我有一个包含 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 列表。选择的标准可以用以下伪代码更好地解释:从表Exercise_Term中选择这样的Ex_Ids,其中Ex_Id在lst_TermId中具有所有相应的Term_Id

例如,从我上面提供的示例表中,

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]
}

查询部分是我的困惑。在这种情况下查询会是什么样的?休息我可以应付。希望问题很清楚。谢谢..

I have a table with 2 columns, Ex_Id and Term_Id, both int type. My table will have many Term Ids for one Exercise Id.

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

etc. Getting a list of Ex_Id is the primary requirement. My function would be like this.

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

That is, I'll be passing a list of Term Ids and I need to get a list of Exercise Ids back matching some criteria. The criteria to select can be better explained with this pseudo-code: SELECT such Ex_Ids FROM table Exercise_Term WHERE Ex_Id has all the corresponding Term_Ids in the lst_TermId

For eg, from the sample table I provided above,

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]
}

Query part is my confusion. What would be the query in this condition like? Rest I can manage. Hope question is clear. Thanks..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜夜流光相皎洁 2024-12-03 04:17:48
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(*)

这是关系划分问题。 “标准”解决方案将使用两个否定(不存在):

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
                  )
        ) 

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

If the combination (Ex_ID, Term_ID) is unique in the table, you can replace COUNT(DISTINCT Term_ID) with COUNT(*)

This is a relational division problem. The "standard" solution would be using two negatives (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
                  )
        ) 

or better in your case:

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
                  )
        ) 

小帐篷 2024-12-03 04:17:48

您可以使用 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,您将获得更好的性能,因为 contains 方法将是 O(1) 而不是 <代码>O(n)。

You can use LINQ. Get the whole table into an IEnumerable of some sort and then use LINQ.
Here is an example:

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);
}

Note that you'll get better performance if your lst_TermId is a HashSet<int>, because the contains method will be O(1) instead of O(n).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文