There is direct support for COUNT(DISTINCT {x})) , but you can imitate it from IGrouping<,> (that is, what group by returns); I'm afraid that I am only βdoingβ C #, so you have to translate to VB ...
select new { Foo= grp.Key, Bar= grp.Select(x => x.SomeField).Distinct().Count() };
Here's an example of Northwind:
using(var ctx = new DataClasses1DataContext()) { ctx.Log = Console.Out; // log TSQL to console var qry = from cust in ctx.Customers where cust.CustomerID != "" group cust by cust.Country into grp select new { Country = grp.Key, Count = grp.Select(x => x.City).Distinct().Count() }; foreach(var row in qry.OrderBy(x=>x.Country)) { Console.WriteLine("{0}: {1}", row.Country, row.Count); } }
TSQL is not exactly what we would like, but it does the job:
SELECT [t1].[Country], ( SELECT COUNT(*) FROM ( SELECT DISTINCT [t2].[City] FROM [dbo].[Customers] AS [t2] WHERE ((([t1].[Country] IS NULL) AND ([t2].[Country] IS NULL)) OR (([t1] .[Country] IS NOT NULL) AND ([t2].[Country] IS NOT NULL) AND ([t1].[Country] = [ t2].[Country]))) AND ([t2].[CustomerID] <> @p0) ) AS [t3] ) AS [Count] FROM ( SELECT [t0].[Country] FROM [dbo].[Customers] AS [t0] WHERE [t0].[CustomerID] <> @p0 GROUP BY [t0].[Country] ) AS [t1]
The results, however, are correctly verified by running it manually:
const string sql = @" SELECT c.Country, COUNT(DISTINCT c.City) AS [Count] FROM Customers c WHERE c.CustomerID != '' GROUP BY c.Country ORDER BY c.Country"; var qry2 = ctx.ExecuteQuery<QueryResult>(sql); foreach(var row in qry2) { Console.WriteLine("{0}: {1}", row.Country, row.Count); }
With the definition of:
class QueryResult { public string Country { get; set; } public int Count { get; set; } }
Marc Gravell Jan 16 '09 at 9:42 2009-01-16 09:42
source share