2009-09-03 61 views
6

我基本上是試圖創建此查詢與NHibernate的ICriteria接口JOINňAnotherTableNHibernate的2.1:</p> <p>SomeTable 1:LEFT與別名(的ICriteria)子查詢

SomeTable有列:PrimaryKey的,NonAggregateColumn
AnotherTable有列:PrimaryKey的,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 

很明顯,使用Projection子查詢效率不高,因爲SQL必須對錶進行兩次掃描(每個聚合一個投影子查詢)。

使用多個GROUP BY也不夠高效。

有沒有解決方案呢?到目前爲止,我一直在使用原始SQL,但對於複雜的報表來說這變得很難處理。

+0

你能澄清你的問題嗎?您顯示的查詢是原生sql。它是否已經返回了預期的數據?你想把它變成標準。爲什麼不HQL? – 2009-09-03 14:31:06

+0

忘記提及:您正在使用ORM。因此,編寫一個查詢,你不必太在意表和外鍵。實體和映射定義更爲重要。那麼這些表格如何映射? SomeTable中是否有列表? AnotherTable中有參考嗎?或兩者? – 2009-09-03 14:32:43

+0

是的,原始查詢返回報告所需的數據。我正在使用NHibernate 2.1。 Criteria API是首選,因爲通過NHLambdaExtensions(我也在使用它)的強打字能力。 我正在使用名稱SomeTable,AnotherTable來使SQL清晰易讀。這是一個真實物體的虛構鏡子。 SomeTable映射對象具有AnotherTable對象的反向一對多集合。 – 2009-09-03 14:38:15

回答

2

不幸的是,Criteria有點受限制。

試試這個:

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
  • 您不能在條款中使用條件和過濾條件製作笛卡爾產品。 (這隻適用於HQL)。
  • 子查詢不能添加到from子句(因爲這會導致笛卡爾積)。您只能將它們放在where子句中(in,exists等)
  • 您或許可以從AnotherTable開始並導航至SomeTable。這可能是一種替代解決方案。
+1

我是通過解決方案意識到這個小組的,但問題是,在真實世界的報告中,我需要按很多列進行分組,以至於SQL會放慢數千條記錄的速度,哦,也許我可以嘗試研究NHibernate的源代碼並貢獻這一天... 現在我將使用原始SQL,感謝您的幫助。 – 2009-09-04 14:20:30

相關問題