Use the Having
method to add grouping to your data and filtering based on that grouping. If criteria already exist, old and new criteria are combined with the AND
operator.
public SimpleQuery Having( SimpleExpression criteria )
criteria
SimpleExpression
db.Albums.AlbumId.Count() > 2
.
Type: SimpleQuery
A SimpleQuery
objct containing a Having clause
Exception | Condition |
---|---|
NullReferenceException |
Having has been called directly on a table reference without a base command (All, FindAllBy etc) |
ArgumentException |
criteria contains zero or more than one SimpleExpression . |
UnresolvableObjectException |
criteria contains a reference to a column not in the select clause of the query. |
Simple.Ado.AdoAdapterException
|
The SimpleExpression supplied to Having has no aggregate function in it
|
Note that issues #285 - #288 are still open with regards to exceptions thrown by Having.
There is no GroupBy
method in Simple.Data. Use the Having
method instead to set aggregate search conditions on columns and Simple.Data will generate the appropriate Group By clause for those searched-for columns not in the Having clause.
The following aggregate methods are supported in SimpleExpressions: Min
, Max
, Avg
, Sum
, and Count
.
For example:
//Max db.Artists.All().Having(db.Artists.Albums.Price.Max() > 10.99); //Min db.Artists.All().Having(db.Artists.Albums.Price.Min() > 5.99); //Avg db.Artists.All().Having(db.Artists.Albums.Price.Avg() > 8.99); //Sum db.Orders.All().Having(db.Orders.OrderDetails.UnitPrice.Sum() > 35); //Count db.Orders.All().Having(db.Orders.OrderDetails.AlbumId.Count() > 2);
Having
takes a single SimpleExpression
with an aggregate function on it as a parameter. Complex search conditions can be constructed by appending multiple Having clauses to the base command - in which case the new criteria is appending to the old using the default AND
operator - or building up complex SimpleExpressions as demonstrated here.
The following example retrieves the name of any artist and the number of their albums in the database if it is greater than two.
SimpleQuery albums = db.Albums.All() .Select(db.Albums.Artists.Name, db.Albums.AlbumId.Count().As("NumberOfAlbums")) .Having(db.Albums.AlbumId.Count() > 2);
Simple.Data sends the following SQL to the database when albums
is evaluated.
select [dbo].[Artists].[Name], Count([dbo].[Albums].[AlbumId]) AS [NumberOfAlbums] from [dbo].[Albums] LEFT JOIN [dbo].[Artists] ON ([dbo].[Artists].[ArtistId] = [dbo].[Albums].[ArtistId]) GROUP BY [dbo].[Artists].[Name] HAVING Count([dbo].[Albums].[AlbumId]) > @p1 @p1 (Int32) = 2
The following example retrieves the name of any artist, number of albums they have recorded and cost to buy them all if the number of albums is more than two OR the cost to buy is greater than 16.99
SimpleQuery albums = db.Albums.All() .Select(db.Albums.Artists.Name, db.Albums.AlbumId.Count().As("NumberOfAlbums"), db.Albums.Price.Sum().As("TotalCost")) .Having(db.Albums.AlbumId.Count() > 2 || db.Albums.Price.Sum() >= 16.99);
Simple.Data sends the following SQL to the database when albums
is evaluated.
select [dbo].[Artists].[Name], Count([dbo].[Albums].[AlbumId]) AS [NumberOfAlbums], Sum([dbo].[Albums].[Price]) AS [TotalCost] from [dbo].[Albums] LEFT JOIN [dbo].[Artists] ON ([dbo].[Artists].[ArtistId] = [dbo].[Albums].[ArtistId]) GROUP BY [dbo].[Artists].[Name] HAVING (Count([dbo].[Albums].[AlbumId]) > @p1 OR Sum([dbo].[Albums].[Price]) >= @p2) @p1 (Int32) = 2 @p2 (Double) = 16.99
The following example uses multiple Having methods to concatenate several aggregate conditions together.
SimpleQuery albums = db.Albums.All() .Select(db.Albums.Artists.Name, db.Albums.AlbumId.Count().As("NumberOfAlbums"), db.Albums.Price.Sum().As("TotalCost")) .Having(db.Albums.AlbumId.Count() > 2) .Having(db.Albums.Price.Sum() >= 16.99);
Simple.Data sends the following SQL to the database when albums
is evaluated.
select [dbo].[Artists].[Name], Count([dbo].[Albums].[AlbumId]) AS [NumberOfAlbums], Sum([dbo].[Albums].[Price]) AS [TotalCost] from [dbo].[Albums] LEFT JOIN [dbo].[Artists] ON ([dbo].[Artists].[ArtistId] = [dbo].[Albums].[ArtistId]) GROUP BY [dbo].[Artists].[Name] HAVING (Count([dbo].[Albums].[AlbumId]) > @p1 AND Sum([dbo].[Albums].[Price]) >= @p2) @p1 (Int32) = 2 @p2 (Double) = 16.99