1

두 개의 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] 
} 

쿼리 부분은 내 혼란이다. 이 조건에서 쿼리는 어떻게됩니까? 내가 할 수있는 휴식. 희망의 질문은 분명합니다. 감사합니다 .. 조합 (Ex_ID, Term_ID) 테이블에서 고유

답변

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 

경우 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를 사용합니다. (가) 방법은 O(1) 대신 O(n) 될 것입니다 포함되어 있기 때문에, 당신의 lst_TermId가 HashSet<int> 경우 당신은 더 나은 성능을 얻을 것이다

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

참고 : 다음은 예입니다.

+0

입니다 .Net 2.0을 사용합니다. 이것은 올바르게 작동하지 않습니다. – nawfal

+0

오 그래, LINQ에 3.5 이상 필요합니다 ... –

+0

어쨌든 이것은 나에게 유용합니다. 집에서 사용하는 것을 고려하십시오. 닷넷 4 :) – nawfal