2009-09-03 5 views
6

에 가입 기본 키, NonAggregateColumn : N AnotherTableNHibernate에 2.1 :</p> <p>SomeTable 1 : LEFT는 별칭 (ICriteria)와 하위 쿼리 기본적으로 내가이 NHibernate에 ICriteria 인터페이스 쿼리 만들기 위해 노력하고

SomeTable은 열이 기본 키, 외래 키, AnotherNonAggregate, YetAnotherNonAggregate

SELECT 
     table1.NonAggregateColumn, 
     subquery.SubQueryAggregate1, 
     subquery.SubQueryAggregate2 
FROM 
     SomeTable AS table1 
     LEFT JOIN 
     (
      SELECT 
       table2.ForeignKey, 
       COUNT(table2.AnotherNonAggregate) AS SubQueryAggregate1, 
       AVG(table2.YetAnotherNonAggregate) AS SubQueryAggregate2 
      FROM AnotherTable AS table2 
      GROUP BY (table2.ForeignKey) 
    ) AS subquery ON subquery.ForeignKey = table1.PrimaryKey 
:
AnotherTable은 열이

SQL이 테이블을 두 번 스캔해야하기 때문에 Projection 하위 쿼리를 사용하는 것이 효율적이지 않습니다 (집계 당 하나의 프로젝션 하위 쿼리).

여러 GROUP BY를 사용하는 것도 효율적이지 않습니다.

해결 방법은 있습니까? 지금까지 원시 SQL을 사용하고 있었지만 복잡한 보고서에서는 다루기 힘들게되었습니다.

+0

질문을 명확하게 할 수 있습니까? 표시중인 쿼리는 원시 SQL입니다. 이미 예상 데이터를 반환합니까? 당신은 기준으로 바꾸고 싶습니다. 왜 HQL을 사용하지 않습니까? –

+0

언급을 잊어 버렸습니다 : ORM을 사용 중입니다. 따라서 쿼리를 작성하기 위해 테이블과 외래 키에 대해 신경 쓸 필요가 없습니다. 엔티티와 매핑 정의가 훨씬 더 중요합니다. 그렇다면이 테이블에 매핑되는 방법은 무엇입니까? SomeTable에 목록이 있습니까? AnotherTable에 참조가 있습니까? 아니면 둘다? –

+0

예, 원래 쿼리는 보고서에 필요한 데이터를 반환합니다. 나는 NHibernate 2.1을 사용하고있다. 기준 API는 NHLambdaExtensions를 통한 강력한 입력 기능으로 인해 선호됩니다 (현재 사용하고 있습니다). SQL을 명확하고 쉽게 읽을 수 있도록하기 위해 SomeTable, AnotherTable이라는 이름을 사용하고 있습니다. 그것은 실제 대상의 가상 거울입니다. SomeTable 매핑 된 객체에는 AnotherTable 객체의 역 일대 다 컬렉션이 있습니다. –

답변

2

불행히도 기준은 조금 제한되어 있습니다.

이 시도 :

당신은 아마 조금 주위를 재생해야
session.CreateCriteria(typeof(SomeTable), "st") 
    .SetProjection(Projections.ProjectionList() 
    .Add(Projections.GroupProperty("st.id")) 
    .Add(Projections.GroupProperty("st.NonAggregateColumn")) 
    .Add(Projections.RowCount(), "rowcount") 
    .Add(Projections.Avg("at.YetAnotherNonAggregate"), "avg")); 
    .CreateCriteria("st.OtherTables", "at", JoinType.InnerJoin) 
    .List<object[]>(); 

, 그것은 추측의 더. 이 방법도 불가능할 수도 있습니다. 일반적으로

select 
    st.id, 
    st.NonAggregateColumn, 
    count() as "rowcount", 
    avg(at.YetAnotherNonAggregate) as "avg" 
from 
    SomeTable st inner join AnotherTable at on ... 
group by 
    st.id, 
    st.NonAggregateColumn 

: 당신은 하위 쿼리가 DetachedCriteria를 사용하여 만들 수 있습니다

  • 이 이런 식으로 뭔가를 생산한다. 자세한 내용은 the docs을 참조하십시오.

  • 기준이있는 데카르트 제품을 만들 수없고 where 절에서 필터링 할 수 없습니다. (이것은 HQL에서만 작동합니다).
  • 하위 조항을 from 절에 추가 할 수 없습니다 (이는 카티 션 곱을 가져 오므로). where 절에만 넣을 수 있습니다 (in, exists 등)
  • AnotherTable으로 시작하여 SomeTable으로 이동할 수 있습니다. 이것은 대체 솔루션 일 수 있습니다.
+1

나는 해결책으로 그룹을 알고 있지만 문제는 실세계 보고서에서 많은 컬럼별로 그룹화해야한다는 것인데, SQL은 1000s의 레코드를 크게 감속 할 것입니다. 어쩌면 내가 NHibernate의 소스를 연구하고이 하루에 기여할 수 있습니다 ... 난 원시 SQL을 사용하여 도움을 주셔서 감사합니다. –