2011-08-03 113 views
6

如何使用QueryOver <>語法編寫以下SQL語句?NHibernate QueryOver <> - SubQuery上的聚合函數

SELECT COUNT(*) FROM (
    SELECT FirstName,LastName 
    FROM People 
    GROUP BY FirstName, LastName 
    ) as sub_t 

我有內部查詢到目前爲止的工作:

var q = _session.QueryOver<Person>() 
    .SelectList(l => l 
     .SelectGroup(x => x.FirstName) 
     .SelectGroup(x => x.LastName)); 

但我不知道如何在一個子查詢包裹這一點,並得到一個行數出來。可以做到嗎?

不幸的是,我的RDBMS方言(MsSqlCe40Dialect)不支持COUNT DISTINCT,所以我沒有使用SelectCountDistinct()的好處。

回答

0

是不是可以使用IQueryOver的RowCount屬性?就像這樣:

var totalRows = _session.QueryOver<Person>() 
.SelectList(l => l 
    .SelectGroup(x => x.FirstName) 
    .SelectGroup(x => x.LastName)).RowCount(); 
+1

不幸的是,GROUP BY沒有保存在你的建議中,我在SqlCe4和SQL Server 2008中進行了測試。在這兩種情況下,生成的查詢都是「SELECT count(*)as y0_ FROM [People] this_」。 – twerq

1

好吧,我不知道用QueryOver behing的原因,但我會做這樣的事情,我認爲它會給你你在找什麼:

Session.CreateCriteria<Person>() 
       .SetProjection(
       Projections.ProjectionList() 
        .Add(Projections.GroupProperty("FirstName"))) 
        .Add(Projections.GroupProperty("LastName"))) 
       .List<Person>().Count(); 

希望有所幫助...

+0

不幸的是,它不會生成所需的SQL - 記錄的整個列表(可能會很大)在計算之前會被加載到.NET代碼中。 – twerq

1

我不熟悉QueryOver,但是當這個類型的計數不可能使用子查詢時,我使用了下面的聚合函數,認爲它可能有用,並且在發佈時發現了一些我以前沒有意識到的問題,所以我也發佈了它們。

注意:中等數據量的速度要慢10倍左右。

聚合方法

SELECT 
COUNT(DISTINCT FirstName+LastName) 
FROM People 

適應特殊情況

類似組合的名字 「張三」 與 「招財MITH」 (假設〜是不是在你的數據集)

SELECT 
COUNT(DISTINCT FirstName+'~'+LastName) 
FROM People 

nulls (As sumes ^是不是在你的數據集)

SELECT 
COUNT(DISTINCT IsNull(FirstName,'^')+'~'+IsNull(LastName,'^')) 
FROM People 

結尾的空白,似乎RTRIM是內在集團通過

SELECT 
COUNT(DISTINCT IsNull(RTrim(FirstName),'^')+'~'+IsNull(Rtrim(LastName),'^')) 
FROM People 

標杆對AMD (80K行數據單四核)

80-100ms - 運行子查詢方法(請參閱OP)

800-1200ms - 集合方法與distinc噸,適應特殊情況似乎沒有明顯的差異。