Hello, welcome to Appsloveworld Technologies, In in theis post will talk about how the group rows using group by, filtering groups, and the difference between where and having clauses.
What is group by clause?
Now, if you look at the definition, the group by clause is used to group a selected set of rows into a set of summary rows by the values of one or more columns or expressions. It is always used in conjunction with one or more aggregate functions.Source
There are many aggregate function available in the SQL server. For example, we have Sum(),Average(), count(), Min(), Max(), etc.
Let’s look at them by example. So I have TblOrganizationEmployee which has got EmployeeName, EmployeeSalary, Country, Adress, and DepartmentId columns. And then I have the Department table which has got the Id and Department Name.
TblOrganizationEmployee and Department are related using foreign key DepartmentId.
if you need sql script of tables you find at the end of post.
If you look at the TblOrganizationEmployee table I have got the EmployeeSalary column.
Let’s say I want the total salary that I am paying within my organization. So obviously, what will you do if you have to do it manually? You will take each row and add them together, but in the SQL server, we have an aggregate function called sum(), which we can use. Like the below query.
select SUM(EmployeeSalary) from [dbo].[TblOrganizationEmployee]
that gives us the total salary.
Similarly, if you want to say let’s say, for example, I want to find out total employees in my organization.
select count(*) from [dbo].[TblOrganizationEmployee]
I want the total salary that I’m paying to my employees by country, how do we achieve this? Using group by.

if you have to do it manually, what will you do?. You will take each Australia record and then add the total salary.
Similarly, you take each India record and add their salaries. so basically what are you doing? You first group the records by country and then sum the salary column across that group.
So that’s why we use group by clause here. So let’s see how to use that.
Select Country, SUM(EmployeeSalary) as TotalSalary
from TblOrganizationEmployee
Group by Country
Query Explantion
if you look at the query that we have written, we are using this Sum() aggregate function to sum up the entire salary that we are paying to our employees.
In our select list, we need to have the country as well as the totalsalary. Now, if you look at for the totalsalary, we didn’t have a column name, so we give a column name by using ‘as’ and we will say totalsalary.
So now let’s look at query select country, the sum of salary from TblOrganizationEmployee.
you are saying, I want the country and the total salary, but you should also tell I want to group by country, so group by country and then calculate the total salaries across that country.so when we execute query you should see the same output.
Let’s see what’s going to happen if I remove this group by clause and then execute this query.
Select Country, SUM(EmployeeSalary) as TotalSalary
from TblOrganizationEmployee
this is going to give an error because you’re saying, select country column, and select the sum of salaries.
so you’re saying you want country column and the total salary, but you are not telling the query to group them by country and then total salaries. if I don’t use the salary country column then it makes sense.
I want the total salaries in the entire table, but when I use the country column you should tell it, group by country as well. So obviously if I execute this query you will get below error
“Msg 8120, Level 16, State 1, Line 4
Column ‘TblOrganizationEmployee.Country’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.”
Now let’s remove the sum aggregate function in the select list and execute the query.
Select Country, EmployeeSalary as TotalSalary
from TblOrganizationEmployee
Group by Country
“Msg 8120, Level 16, State 1, Line 8you will get below error
Column ‘TblOrganizationEmployee.EmployeeSalary’ is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.”
so the columns that you use in the select list, they have to satisfy one of these two conditions. You should either have an aggregate function applied on that column or that column should be part of the group by clause. If none of these conditions are met, then you get the above error.
Group by based on multiple columns
Let’s take this one more level, not only by country. I want to break it down further by DepartmentId.
For example, in Australia, how much is the total salary that I’m paying for each department Marketing,Research and Development, Accounting and Finance employees?.
So we are grouping by multiple columns. we are grouping this total salary first by country and then by DepartmentId. so how do we do that?
It’s pretty simple, in the select list we should now have three columns. We already have a country and TotalSalary columns.
We want the departmentId column as well also specified in the group by clause as well, to tell the SQL server engine, I want you to total the salaries first by country and then by departmentId because we want that breakdown in that order
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary
from TblOrganizationEmployee
group by Country, DepartmentId
when we execute this query, you should see the output.But if you look at our output, it’s not sort
So obviously, we used the order by clause to order the result.
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary
from TblOrganizationEmployee
group by Country, DepartmentId
order by TotalSalary
Now we have seen we can group based on multiple columns.
How to use multiple aggregate functions?
if it’s possible to use multiple aggregate functions let’s understand with example .we are showing the totalsalary by country and DepartmentId. Let’s say I want the total number of employees as well.
Now, if you remember, if you want to find out the total number of employees we can use Count(),
if you look at TblOrganizationEmployee table, we’ve got 11 rows there.
And if I want to find the total number of employees within my organization, I can say count(*) from TblOrganizationEmployee and we get the total count, which is 11.
For performance reasons, instead of using * you as a specific column name, you know, maybe EmployeeName so I get the same result.
select count(EmployeeName) from [dbo].[TblOrganizationEmployee]
So what we want? We not only want total salaries, buy a country, and DepartmentId, we also want the total number of employees. So if you want the total number of employees, we use the count() aggregate function.
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary,COUNT(EmployeeName) as TotalEmployees
from TblOrganizationEmployee
group by Country, DepartmentId
order by TotalSalary
All right, so we have seen how to use multiple aggregate functions as well.
How to filter the groups?
But let’s say I want to see the Marketing(i.e DepartmentId=1) department salaries. Now usually to filter the rows, we can use the where clause, you know, where you can say DepartmentId is equal to 1.
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary,COUNT(EmployeeName) as TotalEmployees
from TblOrganizationEmployee
where DepartmentId=1
group by Country, DepartmentId
order by TotalSalary
The other way to get the same result is instead of using the where clause, we can use the having clause, but the having clause should come after the group by.
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary,COUNT(EmployeeName) as TotalEmployees
from TblOrganizationEmployee
group by Country, DepartmentId
having DepartmentId=1
order by TotalSalary
Difference between having and where clause
Now let’s see what’s the difference between these two queries? when you use where clause, only DepartmentId=1 records are retrieved, and then they are grouped.
But whereas in this when you use the having clause, all the rows from the table TblOrganizationEmployee are retrieved, they are grouped by Country,DepartmentId and then only DepartmentId=1 groups are shown.
Where clause filters row before aggregations, before groupings are performed, whereas having clause filters groups after the aggregations are performed.
Another difference is that you can use having clause only with the select statement, whereas where clause can be used with other than select statements as well, like insert and updates as well.
Aggregate functions cannot be used in the where clause what do we mean by aggregate functions cannot be used in the where clause.Let’s understand with an example.
select * from [dbo].[TblOrganizationEmployee] where count(id)>5
Excute above query you will get the error
“Msg 147, Level 15, State 1, Line 11
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.”
you cannot use aggregate functions with the where clause, whereas aggregate functions can be used in the having clause.
Select Country, DepartmentId, SUM(EmployeeSalary) as TotalSalary,COUNT(EmployeeName) as TotalEmployees
from TblOrganizationEmployee
group by Country, DepartmentId
having COUNT(EmployeeName)=1
order by TotalSalary
Table Script
/****** Object: Table [dbo].[Department] Script Date: 09/22/2020 6:06:10 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Department] [nvarchar](max) NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
)
GO
/****** Object: Table [dbo].[TblOrganizationInfo] Script Date: 09/22/2020 6:06:11 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TblOrganizationInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Location] [nvarchar](50) NULL,
[TravelAgent] [nvarchar](50) NULL,
[BookingAmount] [float] NULL,
CONSTRAINT [PK_TblOrganizationInfo] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
)
GO
SET IDENTITY_INSERT [dbo].[Department] ON
GO
INSERT [dbo].[Department] ([Id], [Department]) VALUES (1, 'Marketing')
GO
INSERT [dbo].[Department] ([Id], [Department]) VALUES (2, 'Research and Development')
GO
INSERT [dbo].[Department] ([Id], [Department]) VALUES (3, 'Accounting and Finance')
GO
SET IDENTITY_INSERT [dbo].[Department] OFF
GO
SET IDENTITY_INSERT [dbo].[TblOrganizationInfo] ON
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (1, 'France', 'Michael', 2000)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (2, 'USA', 'Jackson', 2200)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (3, 'UK', 'Jacob', 3000)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (4, 'India', 'Luke', 2500)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (5, 'USA', 'Michael', 1500)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (6, 'France', 'Jacob', 1000)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (7, 'India', 'Luke', 1200)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (8, 'USA', 'Jacob', 1700)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (9, 'UK', 'Michael', 1900)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (10, 'France', 'Jacob', 2100)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (11, 'USA', 'Luke', 2500)
GO
INSERT [dbo].[TblOrganizationInfo] ([Id], [Location], [TravelAgent], [BookingAmount]) VALUES (12, 'India', 'Michael', 3000)
GO
SET IDENTITY_INSERT [dbo].[TblOrganizationInfo] OFF
GO
The post How to use group by in SQL Server query? appeared first on Software Development | Programming Tutorials.
Read More Articles
- Linq to SQL Group by and Sum in Select | Linq To SQL Group By and Sum
- How send an HTTP POST request to a server from Excel using VBA?
- What is Difference between where and having clauses in SQL server
- How to Use EXCEPT Operator with an example in Sql
- How to use merge statement in the SQL server
- How to write Re-runnable SQL server query
- How to create Cursor in sql server with example
- How to generate random data in sql server for performance testing
- How to write subquery in select statement in Sql
- How to Log record changes in SQL server in an audit table
- Challenging recursive T-SQL query
- Ms Access query to SQL Server - DistinctRow
- Changing NULL's position in sorting
- Display decimal points for DateDiff function in SQL
- MS SQL Temporary table looping
- The server failed to resume the transaction. Linq-To-SQL
- Inserting rows and updating rows on tables that may or may not have primary keys
- Reset cursor's position to the beginng each time the script is being launched
- SQL Server 2008 R2: Finding cells longer than given number
- Copy from SQL Server 2005 to SQL Server 2008 causes x2 data space #SQLHelp
- SQL Server: Select top from each repeated row (Not Distinct)
- Incorrect syntax near '@P0'. exception when create and drop Login in MSSQL
- Delete row from cursor source SQL Server
- How to create monthly attendance report with SQL Server?
- Accumulating (concatenate) values in variable does not work
- Inner join on nested select - when using same column multiple times
- SQL Server array_agg (master - detail)
- cannot connect another sql server instance
- Combine duplicate rows to output a single row
- Querying the same table for a list of databases in MS SQL Server
- How to get a minimum date from multiple identical rows and columns SQL Server
- SELECT Products with only one word in their name
- Using a Temp Table in a Dynamic Pivot
- SSIS Control Flow Diagram is now empty
- Sort SQL table to show first row and Sum of all others
- Meaning of :out in sql
- Large SQL transaction: runs out of memory on PostgreSQL, yet works on SQL Server
- SQL Query that calculates time
- alter a table column and set identity from max existing in that column in sql server 2008
- Generate Unique hash for a field in SQL Server
- Count days in date range with set of exclusions which may overlap
- SQL Server: Count based on date and two different times
- How to completely remove VS 2013 and SQL Server Data Tool
- SQL Native Client & OLEDB
- Problem with multipart sql identifiers
- SQL server - stored procedure - ignore exception
- Can you write a sql statement without spaces between keywords
- SQL Server: if I don't specify a RECOVERY mode for a RESTORE DATABASE, what is the default?
- ordering a self-referencing table by DFS search in sql
- Is it possible to restore a SQL Server database (or a single table) from backup to Databricks Delta table?
- Retrieving multiple rows dynamically using Pivot in SQL
- Different JOIN values depending on the value of another column
- Sql Server 2008 performance
- SQL Year summary starting from given month
- Is it possible to set a timeout for a SQL query on Microsoft SQL Server?
- SQL find duplicate records from past 7 days
- Trying to remove a bit.ly URL at the end of a SQL string
- SqlHierarchyID casting from Datarow
- Azure SQL: Keep alive option
- SQL - Multiple entries in show one instance in c1 with it's correspondent mapping in c2
- Rename all Pivoted Values in SQL
- Scripting your database first versus building the database via SQL Server Management Studio and then generating the script
- sys.databases in a cursor skipping databases
- SQL Server 2012: Constraint has NULL for name. How can I drop this?
- SQL Server 2012 Aggregate on Split Date Time?
- SQL Query optimalisation Merge Table
- Sql Server 2008 Triggers
- Token line number = 1,Token line offset = 56,Token in error = select
- SQL Calculate hours over night with static date
- Time is not getting properly
- Does CakePHP finderQuery work with SQL Server? Where would I debug that?
- Storing and Displaying DateTime from Multiple Servers in Different Time Zones
- Calculation Error in SSAS VS 2005
- Get start and end of each month between two dates
- Connecting to SQL server via socket programming on iOS
- rank function always brings back contiguous ranking
- Where to find the size of SQL Server data types
- is it possible to select EXISTS directly as a bit?
- how to get data dynamically in view basing on fiscal year
- Relevant linq query for the SQL
- SQL Results show up in both queries
- Difference days between datetime and date format
- Creating a Calendar table without recursion
- Getting a query result taken from the same data but with temporary var
- Convert date to varchar
- LINQ to Entities - Subquery is coming back in chunks?
- Join with DateTime and Latest Value from another Table
- How to optimize visit counter SQL query?
- Using case and group-by at the same time
- Queue SQL implementation with a single query
- Is there an equivalent to SHA1() in MS-SQL?
- DTC not working when two transactions are being executed
- SQL Server : query get most school with composer songs
- SQL Statement from DML Trigger
- Easiest way to implement this SQL query?
- Can't connect to docker sql server from NET Core 2.2 Web API
- Querying a linked sql server
- Creating asymmetric keys in SQL Server 2014 for unsafe assemblies
- When does the SQL Server write the results of each Set Statement In and UPDATE
- Use something like LEAST in T-SQL on a datetime field
- .Net Application Installation 2012 with database
- multiple sqlcmd commands in a batch file
- Best Way to Port a SQL Server DB Schema to MySQL
- SqlReader object does not read
- SQL Server Convert String to Date
- How to SUM many rows into 1 row in SQL Server?
- Insert New data into multiple tables with Foreign Key simultaneously in One query in sql server
- SQL Server data tools in visual studio 2015
- SQL executing twice in IIS10 with ASP Classic
- Output TSQL result to textfile in script
- Is there a refactoring tool for SQL Server Database
- Transpose indeterminate number of rows into columns?
- Migrate from SQL to MongoDB?
- Query performance of non clustered index during inner join
- Update a variable in SSIS Custom component not persistent as the process terminates
- Sum of digits of a number in sql server without using traditional loops like while
- SQL Server OFFSET and LIMIT
- How can I optimize a SQL query that performs a count nested inside a group-by clause?
- SQL PIVOT to generate required output
- Rank based on cumulative value
- Join to only the "latest" record with t-sql
- SQL Server: is there a way to prevent user from seeing all databases in an instance?
- Remote MSSQL/ODBC Syncing With Rails
- Paging through Large table in sql 2005
- SQL concatenation via a case statement
- Split a string with 2 delimiters in SQL Server
- Adding and updating columns a posteriori in temp tables in SQL Server
- SQL - Assign Unique ID for DISTINCT records
- ORDER BY with a UNION of disparate datasets (T-SQL)
- How to get the sql queries when trigger was triggered, upto n levels?
- Two values on same variable
- SQL Server data grouping
- Days in every month with two dates
- Size of a single Record ? SQL
- t-sql select query
- Ms-Access - invoke stored procedure that returns recordsset
- Send email with multiple attachment report in PDF through SQL Reporting Services
- Relationship between @@language global variable and default language setting in SQL Server instance
- SQL Server : populate table in 15 minute intervals
- DbSet<TEntity>.Add(TEntity) and Uniqueness
- How to get only phone number not email address in a query
- How to force a SQL Server 2008 database to go Offline
- Selection on single date fails, between dates works fine?
- Return number of rows affected by UPDATE statements
- Getting random N rows by SQL query which will be proportional to the total number of rows in different sections
- SQL Query MyGuitarShop Database
- PHP PDO - The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
- java Instant and MS SQL datetimeoffset
- How to parse JSON data from API response in Python?
- SQL Server: when it's neccessary to use functions/procedures and not queries?
- SQLServerException when using CallableStatement.setObject(int,Object)?
- Join-Free Table structure for Tags
- SQL division giving wrong answer
- How to convert recursive CTE to be usable in SQL Server 2000
- How can I get the last inserted primary key?
- Do I need to explicitly close connections when using GridView control
- Why empty cell throws an error during SQL stored procedure execution
- Why is a table Scan being performed?
- Add and populate a column or add a persisted computed column?
- Calculated field in tableau to find if the first row is Success or Failure