티스토리 뷰

프로그래밍

LINQ 집합 연산 다루기

야라바 2016. 12. 20. 16:47


 ※ LINQ 연관글 모음

 

SQL을 통해서 질의문을 작성하다보면 여러개의 SELECT문을 집합 연산을 통해서 통합 시킬 필요가 있는 경우가 있습니다. 여러 질의를 각각 수행한다음 통합하는 것 보다는 DBMS에게 해당 연산을 모두 맡기는 방법입니다. LINQ에서도 질의 결과에 대한 집합 연산을 메소드를 통해서 수행할 수 있습니다. 

List<Userinfo> userinfo = new List<Userinfo>() {
    new Userinfo { UserID = "hong1", UserName = "홍길동", UserType = "vip", Age = 50, Sex = true},
    new Userinfo { UserID = "parkms", UserName = "박문수", UserType = "vip", Age = 54, Sex = true},
    new Userinfo { UserID = "hongsun", UserName = "홍길순", UserType = "vvip", Age = 43, Sex = false},
    new Userinfo { UserID = "kimsg", UserName = "김삿갓", UserType = "general", Age = 35, Sex = true},
    new Userinfo { UserID = "hwang1", UserName = "황금복", UserType = "general", Age = 29, Sex = false},
    new Userinfo { UserID = "hwangso", UserName = "황소", UserType = "vip", Age = 63, Sex = true},
    new Userinfo { UserID = "kimsan", UserName = "김산", UserType = "general", Age = 23, Sex = true},
    new Userinfo { UserID = "seohee", UserName = "서희", UserType = "vvip", Age = 22, Sex = false}};

var qry = from ui in userinfo
          where ui.Sex == true
          select new { ui.UserName, ui.Age, ui.Sex };
var qry2 = from ui in userinfo
           where ui.Age >= 50 && ui.Age < 60
           select new { ui.UserName, ui.Age, ui.Sex };
var rst = qry.Concat(qry2);
foreach(var itm in rst) 
{
    Console.WriteLine(itm); 
}
Console.WriteLine("---- Distinct ----");
foreach (var itm in rst.Distinct())
{
    Console.WriteLine(itm);
}
Console.WriteLine("---- Union ----");
foreach (var itm in qry.Union(qry2))
{
    Console.WriteLine(itm);
}
Console.WriteLine("---- Intersect ----");
foreach (var itm in qry.Intersect(qry2))
{
    Console.WriteLine(itm);
}
Console.WriteLine("---- Except ----");
foreach (var itm in qry.Except(qry2))
{
    Console.WriteLine(itm);
}

위의 예제는 성별이 true인 사용자를 추출하는 qry와 나이가 50대인 사용자를 추출하는 qry2를 대상으로 집합 연산을 수행하는 코드입니다. 첫번째 Concat() 메소드는 집합 연산은 아니고 단순히 결과를 나란히 붙여서 새로운 결과를 산출하는 역할을 수행합니다. 그래서 "홍길동"과 "박문수"라는 양쪽 질의에 동일하게 등장하는 항목들도 중복해서 그대로 최종 결과에 포함되어 있습니다. 최종 결과에서 동일한 내용을 걷어내는 역할을 수행하는 메소드는 Distinct() 입니다. 복잡한 질의 결과를 다듬는데 유용한 것으로 SQL에서도 DISTINCT 구문을 합니다.

본격적으로 두 결과를 합치는 합집합 연산은 Union()로 수행합니다. 두 결과를 합치지만 동일한 내용을 반복하지는 않습니다. 이러한 점이 단순히 결과를 붙이는 Concat()와 Union()의 근본적인 차이입니다. 두 결과에 모두 존재하는 항목을 추출하는 교집합 연산은 Intersect() 메소드를 사용합니다. 위의 예제에서도 양쪽 결과에 모두 등장하는 "홍길동"과 "박문수"가 교집합 연산 결과입니다. SQL의 합집합 및 교집합 구문도 UNION, INTERSECT를 사용합니다. A-B의 형태의 차집합 연산은 SQL에서는 MINUS 또는 EXCEPT 구문을 사용하는데 LINQ에서는 위의 예제와 같이 Except() 메소드를 사용하면 됩니다.


댓글
댓글쓰기 폼