2009-09-03 2 views
6

でサブクエリに登録しよう:NHibernateは2.1:LEFTは、私は基本的にNHibernateのICriteriaインターフェイスでこのクエリを作成しようとしていますエイリアス(ICriteria)

SomeTable 1:nのAnotherTable

SomeTableは列があります:主キー、NonAggregateColumnを主キー、ForeignKeyの、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がテーブルを2回スキャンする必要があるため、Projectionサブクエリの使用はあまり効率的ではありません(集約ごとに1つの投影サブクエリ)。

複数のGROUP BYを使用することも効率的ではありません。

解決方法はありますか?これまでは生のSQLを使用していましたが、複雑なレポートでは扱いにくくなっています。

+0

質問を明確にすることはできますか?表示しているクエリは、ネイティブSQLです。それはすでに予想されたデータを返していますか?それを基準にしたいと思っています。なぜHQLではないのですか? –

+0

あなたのORMを使用しています。だから、クエリを書くために、あなたはテーブルと外部キーについてあまり気にする必要はありません。より重要なのは、エンティティとマッピングの定義です。では、これらのテーブルをどのようにマップしていますか? SomeTableにリストはありますか? AnotherTableに参照がありますか?または両方? –

+0

はい、元のクエリはレポートに必要なデータを返します。私はNHibernate 2.1を使用しています。 Criteria APIは、NHLambdaExtensions(これも私も使用しています)を介した強力な型指定能力のために好まれます。 私は、SQLを明確かつ読みやすくするために、SomeTable、AnotherTableという名前を使用しています。それは実際の物体の架空の鏡です。 SomeTableマップされたオブジェクトには、AnotherTableオブジェクトの逆1対多コレクションがあります。 –

答えて

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を参照してください。

  • Criteriaを持つデカルト積を作成し、where句でフィルタリングすることはできません。 (これはHQLでのみ動作します)。
  • サブクエリはfrom句に追加できません(これはデカルト積になります)。 where句にのみ入れることができます(inexistsなど)
  • おそらくAnotherTableで始まり、SomeTableに移動できます。これは別の解決方法かもしれません。
+1

私は解決策によってグループを認識していますが、現実世界のレポートでは、SQLが非常に多くの列でグループ化する必要があるということです。多分私はNHibernateのソースを勉強しようとすることができ、この一日に貢献します... 私は生のSQLを今使っています。 –

関連する問題