diff --git a/QueryBuilder.Tests/AggregateTests.cs b/QueryBuilder.Tests/AggregateTests.cs index 32439061..03a6108c 100644 --- a/QueryBuilder.Tests/AggregateTests.cs +++ b/QueryBuilder.Tests/AggregateTests.cs @@ -13,6 +13,58 @@ public void AggregateAsEmpty() Assert.Throws(() => new Query("A").AggregateAs("aggregate", new string[] { })); } + [Fact] + public void AggregateAs() + { + var query = new Query("A").AggregateAs("aggregate", new[] { "Column" }); + + var c = Compile(query); + + Assert.Equal("SELECT AGGREGATE([Column]) AS [aggregate] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT AGGREGATE(`Column`) AS `aggregate` FROM `A`", c[EngineCodes.MySql]); + Assert.Equal("SELECT AGGREGATE(\"Column\") AS \"aggregate\" FROM \"A\"", c[EngineCodes.PostgreSql]); + Assert.Equal("SELECT AGGREGATE(\"COLUMN\") AS \"AGGREGATE\" FROM \"A\"", c[EngineCodes.Firebird]); + } + + [Fact] + public void AggregateAsAlias() + { + var query = new Query("A").AggregateAs("aggregate", new[] { "Column" }, "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT AGGREGATE([Column]) AS [Alias] FROM [A]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT AGGREGATE(`Column`) AS `Alias` FROM `A`", c[EngineCodes.MySql]); + Assert.Equal("SELECT AGGREGATE(\"Column\") AS \"Alias\" FROM \"A\"", c[EngineCodes.PostgreSql]); + Assert.Equal("SELECT AGGREGATE(\"COLUMN\") AS \"ALIAS\" FROM \"A\"", c[EngineCodes.Firebird]); + } + + [Fact] + public void AggregateAsMultipleColumns() + { + var query = new Query("A").AggregateAs("aggregate", new[] { "Column1", "Column2" }); + + var c = Compile(query); + + Assert.Equal("SELECT AGGREGATE(*) AS [aggregate] FROM (SELECT 1 FROM [A] WHERE [Column1] IS NOT NULL AND [Column2] IS NOT NULL) AS [AggregateQuery]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT AGGREGATE(*) AS `aggregate` FROM (SELECT 1 FROM `A` WHERE `Column1` IS NOT NULL AND `Column2` IS NOT NULL) AS `AggregateQuery`", c[EngineCodes.MySql]); + Assert.Equal("SELECT AGGREGATE(*) AS \"AGGREGATE\" FROM (SELECT 1 FROM \"A\" WHERE \"COLUMN1\" IS NOT NULL AND \"COLUMN2\" IS NOT NULL) AS \"AGGREGATEQUERY\"", c[EngineCodes.Firebird]); + Assert.Equal("SELECT AGGREGATE(*) AS \"aggregate\" FROM (SELECT 1 FROM \"A\" WHERE \"Column1\" IS NOT NULL AND \"Column2\" IS NOT NULL) AS \"AggregateQuery\"", c[EngineCodes.PostgreSql]); + } + + [Fact] + public void AggregateAsMultipleColumnsAlias() + { + var query = new Query("A").AggregateAs("aggregate", new[] { "Column1", "Column2" }, "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT AGGREGATE(*) AS [Alias] FROM (SELECT 1 FROM [A] WHERE [Column1] IS NOT NULL AND [Column2] IS NOT NULL) AS [AliasAggregateQuery]", c[EngineCodes.SqlServer]); + Assert.Equal("SELECT AGGREGATE(*) AS `Alias` FROM (SELECT 1 FROM `A` WHERE `Column1` IS NOT NULL AND `Column2` IS NOT NULL) AS `AliasAggregateQuery`", c[EngineCodes.MySql]); + Assert.Equal("SELECT AGGREGATE(*) AS \"ALIAS\" FROM (SELECT 1 FROM \"A\" WHERE \"COLUMN1\" IS NOT NULL AND \"COLUMN2\" IS NOT NULL) AS \"ALIASAGGREGATEQUERY\"", c[EngineCodes.Firebird]); + Assert.Equal("SELECT AGGREGATE(*) AS \"Alias\" FROM (SELECT 1 FROM \"A\" WHERE \"Column1\" IS NOT NULL AND \"Column2\" IS NOT NULL) AS \"AliasAggregateQuery\"", c[EngineCodes.PostgreSql]); + } + [Fact] public void CountAs() { @@ -112,41 +164,81 @@ public void DistinctCountMultipleColumns() [Fact] public void Average() { - var query = new Query("A").AsAverage("TTL"); + var query = new Query("A").AverageAs("TTL"); var c = Compile(query); Assert.Equal("SELECT AVG([TTL]) AS [avg] FROM [A]", c[EngineCodes.SqlServer]); } + [Fact] + public void AverageAlias() + { + var query = new Query("A").AverageAs("TTL", "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT AVG([TTL]) AS [Alias] FROM [A]", c[EngineCodes.SqlServer]); + } + [Fact] public void Sum() { - var query = new Query("A").AsSum("PacketsDropped"); + var query = new Query("A").SumAs("PacketsDropped"); var c = Compile(query); Assert.Equal("SELECT SUM([PacketsDropped]) AS [sum] FROM [A]", c[EngineCodes.SqlServer]); } + [Fact] + public void SumAlias() + { + var query = new Query("A").SumAs("PacketsDropped", "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT SUM([PacketsDropped]) AS [Alias] FROM [A]", c[EngineCodes.SqlServer]); + } + [Fact] public void Max() { - var query = new Query("A").AsMax("LatencyMs"); + var query = new Query("A").MaxAs("LatencyMs"); var c = Compile(query); Assert.Equal("SELECT MAX([LatencyMs]) AS [max] FROM [A]", c[EngineCodes.SqlServer]); } + [Fact] + public void MaxAlias() + { + var query = new Query("A").MaxAs("LatencyMs", "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT MAX([LatencyMs]) AS [Alias] FROM [A]", c[EngineCodes.SqlServer]); + } + [Fact] public void Min() { - var query = new Query("A").AsMin("LatencyMs"); + var query = new Query("A").MinAs("LatencyMs"); var c = Compile(query); Assert.Equal("SELECT MIN([LatencyMs]) AS [min] FROM [A]", c[EngineCodes.SqlServer]); } + + [Fact] + public void MinAlias() + { + var query = new Query("A").MinAs("LatencyMs", "Alias"); + + var c = Compile(query); + + Assert.Equal("SELECT MIN([LatencyMs]) AS [Alias] FROM [A]", c[EngineCodes.SqlServer]); + } } } diff --git a/QueryBuilder.Tests/DefineTest.cs b/QueryBuilder.Tests/DefineTest.cs index 043a891c..297e82b4 100644 --- a/QueryBuilder.Tests/DefineTest.cs +++ b/QueryBuilder.Tests/DefineTest.cs @@ -29,7 +29,7 @@ public void Test_Define_SubQuery() { var subquery = new Query("Products") - .AsAverage("unitprice") + .AverageAs("unitprice") .Define("@UnitsInSt", 10) .Where("UnitsInStock", ">", Variable("@UnitsInSt")); diff --git a/QueryBuilder/Query.Aggregate.cs b/QueryBuilder/Query.Aggregate.cs index 1d381090..6c18800d 100644 --- a/QueryBuilder/Query.Aggregate.cs +++ b/QueryBuilder/Query.Aggregate.cs @@ -5,15 +5,9 @@ namespace SqlKata { public partial class Query { - public Query AsAggregate(string type, string[] columns = null) - { - return AggregateAs( - type, - columns ?? new string[] { }, - null // old interface always uses 'type' as alias name - ); - } - + /********************************************************************** + ** Generic aggregate ** + **********************************************************************/ public Query AggregateAs(string type, IEnumerable columns, string alias = null) { if (columns.Count() == 0) @@ -34,6 +28,10 @@ public Query AggregateAs(string type, IEnumerable columns, string alias return this; } + + /********************************************************************** + ** Count ** + **********************************************************************/ public Query CountAs(string column = null, string alias = null) { return CountAs(column != null ? new[] { column } : new string[] { }, alias); @@ -44,28 +42,45 @@ public Query CountAs(IEnumerable columns, string alias = null) return AggregateAs("count", columns.Count() == 0 ? new[] { "*" } : columns, alias); } - public Query AsAvg(string column) + + /********************************************************************** + ** Average ** + **********************************************************************/ + public Query AvgAs(string column, string alias = null) { - return AsAggregate("avg", new string[] { column }); + return AggregateAs("avg", new[] { column }, alias); } - public Query AsAverage(string column) + + public Query AverageAs(string column, string alias = null) { - return AsAvg(column); + return AvgAs(column, alias); } - public Query AsSum(string column) + + /********************************************************************** + ** Sum ** + **********************************************************************/ + public Query SumAs(string column, string alias = null) { - return AsAggregate("sum", new[] { column }); + return AggregateAs("sum", new[] { column }, alias); } - public Query AsMax(string column) + + /********************************************************************** + ** Maximum ** + **********************************************************************/ + public Query MaxAs(string column, string alias = null) { - return AsAggregate("max", new[] { column }); + return AggregateAs("max", new[] { column }, alias); } - public Query AsMin(string column) + + /********************************************************************** + ** Minimum ** + **********************************************************************/ + public Query MinAs(string column, string alias = null) { - return AsAggregate("min", new[] { column }); + return AggregateAs("min", new[] { column }, alias); } } } diff --git a/SqlKata.Execution/Query.Extensions.cs b/SqlKata.Execution/Query.Extensions.cs index f321400f..15010a4e 100644 --- a/SqlKata.Execution/Query.Extensions.cs +++ b/SqlKata.Execution/Query.Extensions.cs @@ -279,13 +279,13 @@ public static T Aggregate(this Query query, string aggregateOperation, string { var db = CreateQueryFactory(query); - return db.ExecuteScalar(query.AsAggregate(aggregateOperation, columns), transaction, timeout); + return db.ExecuteScalar(query.AggregateAs(aggregateOperation, columns), transaction, timeout); } public static async Task AggregateAsync(this Query query, string aggregateOperation, string[] columns, IDbTransaction transaction = null, int? timeout = null, CancellationToken cancellationToken = default) { var db = CreateQueryFactory(query); - return await db.ExecuteScalarAsync(query.AsAggregate(aggregateOperation, columns), transaction, timeout, cancellationToken); + return await db.ExecuteScalarAsync(query.AggregateAs(aggregateOperation, columns), transaction, timeout, cancellationToken); } public static T Count(this Query query, string[] columns = null, IDbTransaction transaction = null, int? timeout = null) diff --git a/SqlKata.Execution/QueryFactory.cs b/SqlKata.Execution/QueryFactory.cs index 6e6adfbf..7045012a 100644 --- a/SqlKata.Execution/QueryFactory.cs +++ b/SqlKata.Execution/QueryFactory.cs @@ -380,7 +380,7 @@ public async Task ExistsAsync(Query query, IDbTransaction transaction = nu int? timeout = null ) { - return this.ExecuteScalar(query.AsAggregate(aggregateOperation, columns), transaction, timeout ?? this.QueryTimeout); + return this.ExecuteScalar(query.AggregateAs(aggregateOperation, columns), transaction, timeout ?? this.QueryTimeout); } public async Task AggregateAsync( @@ -393,7 +393,7 @@ public async Task ExistsAsync(Query query, IDbTransaction transaction = nu ) { return await this.ExecuteScalarAsync( - query.AsAggregate(aggregateOperation, columns), + query.AggregateAs(aggregateOperation, columns), transaction, timeout, cancellationToken