2011-08-03 19 views
6

Jak napisać następującą instrukcję SQL za pomocą QueryOver <> składnia?NHibernate QueryOver <> - Funkcja agregująca na subQuery

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

Mam zapytanie wewnętrzna pracuje do tej pory:

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

Ale nie mam pojęcia, jak owinąć to w podkwerendzie i uzyskać liczyć wiersz z niego. Czy można to zrobić?

Niestety mój dialekt RDBMS (MsSqlCe40Dialect) nie obsługuje COUNT DISTINCT, więc nie mam korzyści z używania SelectCountDistinct().

Odpowiedz

0

Nie można użyć właściwości RowCount w IQueryOver? Tak:

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

Niestety GROUP BY nie jest zachowana w twojej sugestii, testowałem w SqlCe4 i SQL Server 2008. Wygenerowane zapytanie to "SELECT count (*) as y0_ FROM [People] this_" w obu przypadkach. – twerq

1

Ok, nie znam przyczyny behing użyciu QueryOver, ale chciałbym zrobić coś takiego, myślę, że to da ci to, czego szukasz:

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

Nadzieję, że pomaga ...

+0

Niestety, to nie tworzy pożądanego kodu SQL - cała lista rekordów (które mogą być ogromne) jest ładowana do kodu .NET, zanim zostanie policzona. – twerq

1

Nie jestem zaznajomiony z QueryOver, ale użyłem następującej funkcji agregującej, gdy sub-kwerenda nie była możliwa dla tego typu liczenia, uważam, że może być przydatna, i podczas gdy posting odkrył kilka problemy, o których wcześniej nie wiedziałem, więc też je opublikowałem.

Uwaga: jest około 10 razy wolniejsza przy umiarkowanych ilościach danych.

sposób sumaryczny

SELECT 
COUNT(DISTINCT FirstName+LastName) 
FROM People 

pomieścić szczególnych przypadkach

podobnej nazwy kombinacja "Joe Smith" vs "Joes mith" (Zakłada ~ nie jest w zestawie danych)

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

nulls (As resuscytacja^nie jest w zestawie danych)

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

zbędne spacje, wydaje RTRIM jest nieodłączną częścią Grupy Przez

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

Benchmarking (80k wierszy danych na platformie AMD single Quad Core)

80-100ms - uruchom metodę subdomen (zobacz OP)

800-1200ms - metoda agregatowa z distinc t, przystosowanie do specjalnych przypadków nie wydaje się zauważalnie istotnej różnicy.

Powiązane problemy