그룹 조인이란?
그룹 조인이랑 두 개 이상의 데이터 집합에서 일치하는 키를 기준으로 그룹화된 데이터를 반환합니다. C#의 Linq에서 키를 기준으로 그룹화된 데이터를 구하기 위해 GroupJoin() 메서드를 사용할 수 있습니다. GroupJoin() 메서드는 Join() 메서드와 GroupBy() 메서드의 기능이 하나로 합쳐진 메서드입니다.
예를 들어, 두 개의 데이터 집합(Employee, Department)이 존재합니다.
데이터 집합 Employee에는 부서 코드가 1000인 사원이 2명, 2000인 사원이 4명, 3000인 사원이 1명입니다. 하지만, 데이터 집합 Department의 부서 코드에는 3000인 데이터가 없으므로 Employee와 Department를 그룹 조인하면, 다음과 같은 결과가 출력됩니다.
GroupJoin 메서드
C#의 Linq에서 제공하는 GroupJoin() 메서드를 사용하여 두 개의 데이터 집합을 그룹 조인할 수 있습니다. GroupJoin() 메서드는 두 가지 오버로드된 버전이 존재하며, 비교자를 사용한다는 차이점이 있습니다.
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector);
public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
IEqualityComparer<TKey> comparer);
GroupJoin() 메서드를 사용하기 위해 다음 내용을 숙지합시다.
외부 데이터 소스
- GroupJoin() 메서드를 호출하는 데이터 집합입니다.
내부 데이터 소스
- GroupJoin() 메서드를 호출하는 데이터 집합과 Join되는 데이터 집합입니다.
- 내부 데이터 소스는 GroupJoin() 메서드의 첫 번째 매개변수입니다.
- IEnumerable<TInner> inner
외부 키 선택자
- 외부 데이터 소스(GroupJoin() 메서드를 호출하는 데이터 집합)에서 Join에 필요한 키를 가져옵니다.
- 외부 키 선택자는 GroupJoin() 메서드의 두 번째 매개변수입니다.
- Func<TOuter, TKey> outerKeySelector
내부 키 선택자
- 내부 데이터 소스(GroupJoin() 메서드의 첫 번째 매개변수)에서 Join에 필요한 키를 가져옵니다.
- 내부 키 선택자는 GroupJoin() 메서드의 세 번째 매개변수입니다.
- Func<TInner, TKey> innerKeySelector
결과 선택자
- Join 결과에서 추출하고 싶은 데이터를 작성합니다.
- Select절과 유사합니다.
- 결과 선택자는 GroupJoin() 메서드의 네 번째 매개변수입니다.
- Func<TOuter, IEnumerable<TInner>, TResult> resultSelector
샘플 데이터
이번 포스팅에서는 사용자 정의 클래스인 Employee, Department 타입의 데이터 집합을 사용합니다.
[Employee 클래스]
public class Employee {
public string Emp_Code { get; set; } // 사원코드
public string Emp_Name { get; set; } // 사원명
public string Dept_Code { get; set; } // 부서코드
public static List<Employee> GetEmployees()
{
return new List<Employee>()
{
new Employee { Emp_Code = "1", Emp_Name = "홍길동", Dept_Code = "1000"},
new Employee { Emp_Code = "2", Emp_Name = "호날두", Dept_Code = "1000"},
new Employee { Emp_Code = "3", Emp_Name = "김첨지", Dept_Code = "2000"},
new Employee { Emp_Code = "4", Emp_Name = "다람쥐", Dept_Code = "2000"},
new Employee { Emp_Code = "5", Emp_Name = "김환자", Dept_Code = "2000"},
new Employee { Emp_Code = "6", Emp_Name = "마이콜", Dept_Code = "2000"},
new Employee { Emp_Code = "7", Emp_Name = "나랑두", Dept_Code = "3000"}
};
}
}
[Department 클래스]
public class Department
{
public string Dept_Code { get; set; } // 부서코드
public string Dept_Name { get; set; } // 부서명
public static List<Department> GetDeptments()
{
return new List<Department>()
{
new Department { Dept_Code = "1000", Dept_Name = "영업"},
new Department { Dept_Code = "2000", Dept_Name = "기획"}
};
}
}
예제 1. 질의 구문
다음 예제는 질의 구문을 사용하여 Employee 데이터 집합의 Dept_Code(부서 코드)와 Department 데이터 집합의 Dept_Code(부서 코드)가 일치한 데이터를 추출합니다.
질의 구문에는 GroupJoin() 메서드를 사용할 수 없으므로 join 연산자와 into 연산자를 함께 사용합니다.
class Program
{
static void Main(string[] args)
{
var GroupJoinQueryResult = (from department in Department.GetDeptments()
// Inner Join
join employee in Employee.GetEmployees()
on department.Dept_Code equals employee.Dept_Code
// Group 결과
into groupResult
// select 선택자
select new
{
department,
groupResult
});
foreach (var result in GroupJoinQueryResult) {
Console.WriteLine("부서명 :" + result.department.Dept_Name);
foreach (var employee in result.groupResult)
{
Console.WriteLine("사원 코드 : " + employee.Emp_Code + " , 사원명 : " + employee.Emp_Name);
}
Console.WriteLine();
}
}
}
[실행 결과]
부서명 :영업
사원 코드 : 1 , 사원명 : 홍길동
사원 코드 : 2 , 사원명 : 호날두
부서명 :기획
사원 코드 : 3 , 사원명 : 김첨지
사원 코드 : 4 , 사원명 : 다람쥐
사원 코드 : 5 , 사원명 : 김환자
사원 코드 : 6 , 사원명 : 마이콜
예제 2. 메서드 구문
다음 예제는 메서드 구문을 사용하여 Employee 데이터 집합의 Dept_Code(부서 코드)와 Department 데이터 집합의 Dept_Code(부서 코드)가 일치한 데이터를 추출합니다.
class Program
{
static void Main(string[] args)
{
var GroupJoinMethodResult = Department.GetDeptments()
.GroupJoin(Employee.GetEmployees(),
department => department.Dept_Code,
employee => employee.Dept_Code,
(department, employee) => new
{
department,
employee
});
foreach (var result in GroupJoinMethodResult) {
Console.WriteLine("부서명 :" + result.department.Dept_Name);
foreach (var employee in result.employee)
{
Console.WriteLine("사원 코드 : " + employee.Emp_Code + " , 사원명 : " + employee.Emp_Name);
}
Console.WriteLine();
}
}
}
[실행 결과]
부서명 :영업
사원 코드 : 1 , 사원명 : 홍길동
사원 코드 : 2 , 사원명 : 호날두
부서명 :기획
사원 코드 : 3 , 사원명 : 김첨지
사원 코드 : 4 , 사원명 : 다람쥐
사원 코드 : 5 , 사원명 : 김환자
사원 코드 : 6 , 사원명 : 마이콜
'C# > LINQ' 카테고리의 다른 글
[C#]LINQ 크로스 조인(Cross Join) (0) | 2022.08.07 |
---|---|
[C#]LINQ 왼쪽 조인(Left Join) (0) | 2022.08.06 |
[C#]LINQ 내부 조인(Inner Join) - Join 메서드 (0) | 2022.08.06 |
[C#]LINQ 데이터 그룹화 - GroupBy 메서드 (1) | 2022.08.04 |
[C#]LINQ 누적기 함수 - Aggregate 메서드 (0) | 2022.08.03 |
댓글