다음을 통해 공유


방법: 시퀀스의 요소 그룹화(LINQ to SQL)

업데이트: November 2007

GroupBy 연산자는 시퀀스의 요소를 그룹화합니다. 다음 예제에서는 Northwind 데이터베이스를 사용합니다.

참고:

GroupBy 쿼리의 Null 열 값은 종종 InvalidOperationException을 throw합니다. 자세한 내용은 문제 해결(LINQ to SQL)의 "GroupBy InvalidOperationException" 단원을 참조하십시오.

예제

다음 예제에서는 CategoryID에 따라 Products를 구분합니다.

Dim prodQuery = From prod In db.Products _
    Group prod By prod.CategoryID Into grouping = Group

For Each grp In prodQuery
    Console.WriteLine(vbNewLine & "CategoryID Key = {0}:", _
        grp.CategoryID)
    For Each listing In grp.grouping
        Console.WriteLine(vbTab & listing.ProductName)
    Next
Next
IQueryable<IGrouping<Int32?, Product>> prodQuery =
    from prod in db.Products
    group prod by prod.CategoryID into grouping
    select grouping;

foreach (IGrouping<Int32?, Product> grp in prodQuery)
{
    Console.WriteLine("\nCategoryID Key = {0}:", grp.Key);
    foreach (Product listing in grp)
    {
        Console.WriteLine("\t{0}", listing.ProductName);
    }
}

다음 예제에서는 Max를 사용하여 각 CategoryID에 대한 최대 단가를 검색합니다.

Dim query = From p In db.Products _
    Group p By p.CategoryID Into g = Group _
    Select CategoryID, MaxPrice = g.Max(Function(p) p.UnitPrice)
var q =
    from p in db.Products
    group p by p.CategoryID into g
    select new
    {
        g.Key,
        MaxPrice = g.Max(p => p.UnitPrice)
    };

다음 예제에서는 Average를 사용하여 각 CategoryID에 대한 평균 UnitPrice를 검색합니다.

Dim q2 = From p In db.Products _
    Group p By p.CategoryID Into g = Group _
    Select CategoryID, AveragePrice = g.Average(Function(p) _
        p.UnitPrice)
var q2 =
    from p in db.Products
    group p by p.CategoryID into g
    select new
    {
        g.Key,
        AveragePrice = g.Average(p => p.UnitPrice)
    };

다음 예제에서는 Sum을 사용하여 각 CategoryID에 대한 총 UnitPrice를 검색합니다.

Dim priceQuery = From prod In db.Products _
    Group prod By prod.CategoryID Into grouping = Group _
    Select CategoryID, TotalPrice = grouping.Sum(Function(p) _
        p.UnitPrice)

For Each grp In priceQuery
    Console.WriteLine("Category = {0}, Total price = {1}", _
        grp.CategoryID, grp.TotalPrice)
Next
var priceQuery =
    from prod in db.Products
    group prod by prod.CategoryID into grouping
    select new
    {
        grouping.Key,
        TotalPrice = grouping.Sum(p => p.UnitPrice)
    };

foreach (var grp in priceQuery)
{
    Console.WriteLine("Category = {0}, Total price = {1}",
        grp.Key, grp.TotalPrice);
}

다음 예제에서는 Count를 사용하여 각 CategoryID에서 할인된 Products의 수를 검색합니다.

Dim disconQuery = From prod In db.Products _
    Group prod By prod.CategoryID Into grouping = Group _
    Select CategoryID, NumProducts = grouping.Count(Function(p) _
        p.Discontinued)

For Each prodObj In disconQuery
    Console.WriteLine("CategoryID = {0}, Discontinued# = {1}", _
        prodObj.CategoryID, prodObj.NumProducts)
Next
var disconQuery =
    from prod in db.Products
    group prod by prod.CategoryID into grouping
    select new
    {
        grouping.Key,
        NumProducts = grouping.Count(p => p.Discontinued)
    };

foreach (var prodObj in disconQuery)
{
    Console.WriteLine("CategoryID = {0}, Discontinued# = {1}",
        prodObj.Key, prodObj.NumProducts);
}

다음 예제에서는 아래의 where 절을 사용하여 최소 10개의 제품이 있는 범주를 모두 검색합니다.

Dim prodCountQuery = From prod In db.Products _
    Group prod By prod.CategoryID Into grouping = Group _
    Where grouping.Count >= 10 _
    Select CategoryID, ProductCount = grouping.Count

For Each prodCount In prodCountQuery
    Console.WriteLine("CategoryID = {0}, Product count = {1}", _
        prodCount.CategoryID, prodCount.ProductCount)
Next
var prodCountQuery =
    from prod in db.Products
    group prod by prod.CategoryID into grouping
    where grouping.Count() >= 10
    select new
    {
        grouping.Key,
        ProductCount = grouping.Count()
    };

foreach (var prodCount in prodCountQuery)
{
    Console.WriteLine("CategoryID = {0}, Product count = {1}",
        prodCount.Key, prodCount.ProductCount);
}

다음 예제에서는 CategoryID 및 SupplierID에 따라 제품을 그룹화합니다.

Dim prodQuery = From prod In db.Products _
    Group prod By Key = New With {prod.CategoryID, prod.SupplierID} _
        Into grouping = Group

For Each grp In prodQuery
    Console.WriteLine(vbNewLine & "CategoryID {0}, SupplierID {1}", _
        grp.Key.CategoryID, grp.Key.SupplierID)
    For Each listing In grp.grouping
        Console.WriteLine(vbTab & listing.ProductName)
    Next
Next
var prodQuery =
    from prod in db.Products
    group prod by new
    {
        prod.CategoryID,
        prod.SupplierID
    }
    into grouping
    select new { grouping.Key, grouping };

foreach (var grp in prodQuery)
{
    Console.WriteLine("\nCategoryID {0}, SupplierID {1}",
        grp.Key.CategoryID, grp.Key.SupplierID);
    foreach (var listing in grp.grouping)
    {
        Console.WriteLine("\t{0}", listing.ProductName);
    }
}

다음 예제에서는 두 가지 제품 시퀀스를 반환합니다. 첫 번째 시퀀스에는 단가가 10 이하인 제품이 들어 있습니다. 두 번째 시퀀스에는 단가가 10보다 큰 제품이 들어 있습니다.

Dim priceQuery = From prod In db.Products _
    Group prod By Key = New With {.Criterion = prod.UnitPrice > 10} _
        Into grouping = Group Select Key, grouping

For Each prodObj In priceQuery
    If prodObj.Key.Criterion = False Then
        Console.WriteLine("Prices 10 or less:")
    Else
        Console.WriteLine("\nPrices greater than 10")
        For Each listing In prodObj.grouping
            Console.WriteLine("{0}, {1}", listing.ProductName, _
                listing.UnitPrice)
        Next
    End If
Next
var priceQuery =
    from prod in db.Products
    group prod by new
    {
        Criterion = prod.UnitPrice > 10
    }
    into grouping
    select grouping;

foreach (var prodObj in priceQuery)
{
    if (prodObj.Key.Criterion == false)
        Console.WriteLine("Prices 10 or less:");
    else
        Console.WriteLine("\nPrices greater than 10");
    foreach (var listing in prodObj)
    {
        Console.WriteLine("{0}, {1}", listing.ProductName,
            listing.UnitPrice);
    }
}

GroupBy 연산자는 하나의 키 인수만을 받아들일 수 있습니다. 둘 이상의 키로 그룹화해야 하는 경우 다음 예제처럼 익명 형식을 만들어야 합니다.

Dim custRegionQuery = From cust In db.Customers _
    Group cust.ContactName By Key = New With _
        {cust.City, cust.Region} Into grouping = Group

For Each grp In custRegionQuery
    Console.WriteLine(vbNewLine & "Location Key: {0}", grp.Key)
    For Each listing In grp.grouping
        Console.WriteLine(vbTab & "{0}", listing)
    Next
Next
var custRegionQuery =
    from cust in db.Customers
    group cust.ContactName by new { City = cust.City, Region = cust.Region };

foreach (var grp in custRegionQuery)
{
    Console.WriteLine("\nLocation Key: {0}", grp.Key);
    foreach (var listing in grp)
    {
        Console.WriteLine("\t{0}", listing);
    }
}

참고 항목

개념

샘플 데이터베이스 다운로드(LINQ to SQL)

기타 리소스

쿼리 예제(LINQ to SQL)