Home > Software design >  Select query on a linking table to get all related results per primary key in one field as comma sep
Select query on a linking table to get all related results per primary key in one field as comma sep

Time:12-28

I have a database with 3 tables; Employees, Clients, and a linking table. The Employees and Clients tables have a many-to-many relationship. One or more employee(s) can be working with one or more client(s). Some employees (generally new employees) may not be working with any clients. The Employees table has the following fields; Employoee_ID, Employee_FirstName, Employee_LastName The Clients table has the following fields; Client_ID, Client_Name, Client_Address.

I need to write a SQL query on Microsoft SQL that selects Employoee_ID, Employee_FirstName, Employee_LastName, then has a Clients field which lists all of the clients ID's that each employee is working with in one single field.

Tables:

Employees:

Employoee_ID Employee_FirstName Employee_LastName
1 George Washington
2 John Adams
3 Tom Jefferson

Clients:

Client_ID Client_Name Client_Address
11 ClientAl 1 Al Road
22 ClientBill 2 Bill Road
33 ClientChris 3 Chris Road
44 ClientCharlie 30 Charlie Street

Linking Table

EmployeeID ClientID
1 11
2 22
2 33
3 44

I need a Microsoft SQL Query that will give the following output; (Each employee is listed ONLY once and all of his/ her related clients' IDs are shown in the same row, in one field, as comma seperated/ semicolon separated values.

Employoee_ID Employee_FirstName Employee_LastName Clients
1 George Washington 11
2 John Adams 22;33
3 Tom Jefferson 44

Please advise if you know of a way to do write a query to get the results above. Currently, I am getting each employee multiple times with each client ID in separate rows.

I tried using SELECT distinct & other functions but couldn't generate comma separated client ID's in one field for each employee.

Currently my query is listing Employee "John Adams" twice, once with each of its clients.

Employoee_ID Employee_FirstName Employee_LastName Clients
1 George Washington 11
2 John Adams 22
2 John Adams 33
3 Tom Jefferson 44

Tried select (distinct) EmployeeID to get each employee only listed once but didn't work in listing all related clientID's in one field.

CodePudding user response:

You could use string_agg - STRING_AGG (Transact-SQL)

select e.employee_id,
       e.employee_firstname,
       e.employee_lastname,
       string_agg(cli.clientid, ',') AS clients
  from Employees e
left join [linking table] cli
  on e.employee_id= cli.employeeid;

CodePudding user response:

Since SQL Server 2017 you can achieve the desired output via group by and STRING_AGG function:

select 
  e.Employoee_ID,
  MAX(e.Employee_FirstName) as Employee_FirstName,
  MAX(e.Employee_LastName) as Employee_LastName,
  STRING_AGG(CONVERT(NVARCHAR(max),ClientID), ';') as Clients
from employoee e
join links l on e.Employoee_ID = l.EmployeeID
join client c on c.Client_ID = l.ClientID
group by e.Employoee_ID

Output:

Employoee_ID Employee_FirstName Employee_LastName Clients
1 George Washington 11
2 John Adams 22;33
3 Tom Jefferson 44

Check out the demo fiddle.

  • Related