Max ()를 사용하여 단일 행을 선택하는 LINQ


95

NHibernate에서 반환 된 IQueryable에 LINQ를 사용하고 있으며 두 필드에서 최대 값을 가진 행을 선택해야합니다.

내가 고수하는 부분을 단순화했습니다. 한 필드에서 최대 값을 사용하여 테이블에서 한 행을 선택해야합니다.

var table = new Table { new Row(id: 1, status: 10), new Row(id: 2, status: 20) }

from u in table
group u by 1 into g
where u.Status == g.Max(u => u.Status)
select u

이것은 부정확하지만 올바른 형식을 찾을 수 없습니다.

BTW, 내가 실제로 달성하려는 것은 대략 다음과 같습니다.

var clientAddress = this.repository.GetAll()
    .GroupBy(a => a)
    .SelectMany(
            g =>
            g.Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.AddressReference == g.Max(x => x.AddressReference) && 
                a.StartDate == g.Max(x => x.StartDate)))
    .SingleOrDefault();

위의 람다로 시작했지만 LINQPad를 사용하여 Max ()를 선택하는 구문을 시도하고 해결했습니다.

최신 정보

GroupBy 제거가 핵심이었습니다.

var all = this.repository.GetAll();

var address = all
            .Where(
                a =>
                a.Reference == clientReference && 
                a.Status == ClientStatus.Live && 
                a.StartDate == all.Max(x => x.StartDate) &&
                a.AddressReference == all.Max(x => x.AddressReference))
            .SingleOrDefault();


@ M.Babcock 아주 멀리 아래 질문에 좋은 답변이 있었다 : stackoverflow.com/a/6330485/444244
Boggin

그것보다 훨씬 더 나은 것들이 있습니다 ...
M.Babcock 2012

한 번 봐 가지고 답을 .
Sergey Brunov 2012

@Serge 나는 morelinq 가 최고 라는 데 동의 하지만이 프로젝트가 새로운 라이브러리를 추가하는 데 방해가 될까봐 걱정됩니다.
Boggin

답변:


230

왜 여기에 그룹화하는지 모르겠습니다.

이 시도:

var maxValue = table.Max(x => x.Status)
var result = table.First(x => x.Status == maxValue);

table번만 반복되는 다른 접근 방식 은 다음과 같습니다.

var result = table.OrderByDescending(x => x.Status).First();

경우에 유용 tableIEnumerable<T>메모리에 존재하지 않은 것 또는이 실시간으로 계산된다.


1
나는 그룹화를 제거하고 그것을 작동시킬 수 있다는 것을 알았다 : from u in User_Accounts where u.Status == User_Accounts.Max(y => y.Status) select u
Boggin

1
람다 구문을 중첩 할 수도 있습니다. table.First(x => x.Status == table.Max(x => x.Status))
Landon Poch

13
@LandonPoch : 이것은 좋은 생각이 아닙니다 table..
Daniel Hilgarth

2
@Daniel Hilgarth : 잘 잡아! 실제로 테이블의 모든 행당 최대 값을 계산합니다. 내 잘못이야.
Landon Poch

17

다음을 수행 할 수도 있습니다.

(from u in table
orderby u.Status descending
select u).Take(1);

13

상태별로 그룹화하고 가장 큰 그룹에서 행을 선택할 수 있습니다.

table.GroupBy(r => r.Status).OrderByDescending(g => g.Key).First().First();

First()번째 그룹은 첫 번째 그룹 (상태가 가장 큰 행 집합)을 가져옵니다. 두 번째 First()는 해당 그룹의 첫 번째 행을 가져옵니다.
상태가 항상 unqiue이면 두 번째 First()Single().


7

첫 번째 질문을 해결하면서 특정 기준에 따라 그룹화 된 여러 행을 최대 값을 가진 다른 열과 함께 가져와야하는 경우 다음과 같이 할 수 있습니다.

var query =
    from u1 in table
    join u2 in (
        from u in table
        group u by u.GroupId into g
        select new { GroupId = g.Key, MaxStatus = g.Max(x => x.Status) }
    ) on new { u1.GroupId, u1.Status } equals new { u2.GroupId, Status = u2.MaxStatus}
    select u1;

0

더 많은 예 :

따르다:

 qryAux = (from q in qryAux where
            q.OrdSeq == (from pp in Sessao.Query<NameTable>() where pp.FieldPk
            == q.FieldPk select pp.OrdSeq).Max() select q);

같음 :

 select t.*   from nametable t  where t.OrdSeq =
        (select max(t2.OrdSeq) from nametable t2 where t2.FieldPk= t.FieldPk)

-1

한 줄로 간단히 :

var result = table.First(x => x.Status == table.Max(y => y.Status));

두 가지 조치가 있습니다. 내부 동작은 최대 값을 찾는 것이고 외부 동작은 원하는 객체를 얻기위한 것입니다.


이 방법은 잘못된 생각이라고 지적 된 수용된 답변에 대한 의견에서 논의되었습니다.
Boggin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.