SQL Sever 2008: many-to-many relationship: Concatenation in SELECT query [duplicate]









up vote
1
down vote

favorite













This question already has an answer here:



  • How to make a query with group_concat in sql server [duplicate]

    4 answers



There are 3 tables:



  1. Project

  2. Tool

  3. LinkProjectTool

I need a query that lists everything in the Project table plus an extra column called ProjectTools. This column should contain a comma delimited string with all the tool names belonging to each project.



The data is:



Table Project:
ID Name Client
0 table Anna
1 chair Bobby
2 workbench James
3 window Jenny
4 shelves Matthew

Table Tool:
ID Name
0 hammer
1 measuring tape
2 pliers
3 scissors
4 spanner
5 saw
6 screwdriver

Table LinkProjectTool:
IDProject IDTool
0 0
0 3
2 1
2 4
2 5


The result should be:



ID Name Client ProjectTools
0 table Anna hammer, scissors
1 chair Bobby
2 workbench James measuring tape, spanner, saw
3 window Jenny
4 shelves Matthew


Here are the queries I used to create these tables:



CREATE TABLE [dbo].[Project]
(
[ID] [int] NOT NULL,
[Name] [nvarchar](15) NOT NULL,
[Client] [nvarchar](15) NULL
)

INSERT INTO [dbo].[Project]
(ID, Name, Client)
VALUES
(0, 'table', 'Anna'),
(1, 'chair', 'Bobby'),
(2, 'workbench', 'James'),
(3, 'window', 'Jenny'),
(4, 'shelves', 'Matthew')

CREATE TABLE [dbo].[Tool](
[ID] [tinyint] IDENTITY(0,1) NOT NULL,
[Name] [nvarchar](30) NULL,
CONSTRAINT [PK_Tool] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO [dbo].Tool
(Name)
VALUES
('hammer'),
('measuring tape'),
('pliers'),
('scissors'),
('spanner'),
('saw'),
('screwdriver')

CREATE TABLE [dbo].LinkProjectTool
(
[IDProject] [int] NOT NULL,
[IDTool] [tinyint] NULL
)

INSERT INTO [dbo].LinkProjectTool
(IDProject, IDTool)
VALUES
(0, 0),
(0, 3),
(2, 1),
(2, 4),
(2, 5)


Could you, please, help?



Thank you.










share|improve this question















marked as duplicate by Shnugo sql
Users with the  sql badge can single-handedly close sql questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 11 at 9:55


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
    – Shnugo
    Nov 11 at 9:56














up vote
1
down vote

favorite













This question already has an answer here:



  • How to make a query with group_concat in sql server [duplicate]

    4 answers



There are 3 tables:



  1. Project

  2. Tool

  3. LinkProjectTool

I need a query that lists everything in the Project table plus an extra column called ProjectTools. This column should contain a comma delimited string with all the tool names belonging to each project.



The data is:



Table Project:
ID Name Client
0 table Anna
1 chair Bobby
2 workbench James
3 window Jenny
4 shelves Matthew

Table Tool:
ID Name
0 hammer
1 measuring tape
2 pliers
3 scissors
4 spanner
5 saw
6 screwdriver

Table LinkProjectTool:
IDProject IDTool
0 0
0 3
2 1
2 4
2 5


The result should be:



ID Name Client ProjectTools
0 table Anna hammer, scissors
1 chair Bobby
2 workbench James measuring tape, spanner, saw
3 window Jenny
4 shelves Matthew


Here are the queries I used to create these tables:



CREATE TABLE [dbo].[Project]
(
[ID] [int] NOT NULL,
[Name] [nvarchar](15) NOT NULL,
[Client] [nvarchar](15) NULL
)

INSERT INTO [dbo].[Project]
(ID, Name, Client)
VALUES
(0, 'table', 'Anna'),
(1, 'chair', 'Bobby'),
(2, 'workbench', 'James'),
(3, 'window', 'Jenny'),
(4, 'shelves', 'Matthew')

CREATE TABLE [dbo].[Tool](
[ID] [tinyint] IDENTITY(0,1) NOT NULL,
[Name] [nvarchar](30) NULL,
CONSTRAINT [PK_Tool] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO [dbo].Tool
(Name)
VALUES
('hammer'),
('measuring tape'),
('pliers'),
('scissors'),
('spanner'),
('saw'),
('screwdriver')

CREATE TABLE [dbo].LinkProjectTool
(
[IDProject] [int] NOT NULL,
[IDTool] [tinyint] NULL
)

INSERT INTO [dbo].LinkProjectTool
(IDProject, IDTool)
VALUES
(0, 0),
(0, 3),
(2, 1),
(2, 4),
(2, 5)


Could you, please, help?



Thank you.










share|improve this question















marked as duplicate by Shnugo sql
Users with the  sql badge can single-handedly close sql questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 11 at 9:55


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
    – Shnugo
    Nov 11 at 9:56












up vote
1
down vote

favorite









up vote
1
down vote

favorite












This question already has an answer here:



  • How to make a query with group_concat in sql server [duplicate]

    4 answers



There are 3 tables:



  1. Project

  2. Tool

  3. LinkProjectTool

I need a query that lists everything in the Project table plus an extra column called ProjectTools. This column should contain a comma delimited string with all the tool names belonging to each project.



The data is:



Table Project:
ID Name Client
0 table Anna
1 chair Bobby
2 workbench James
3 window Jenny
4 shelves Matthew

Table Tool:
ID Name
0 hammer
1 measuring tape
2 pliers
3 scissors
4 spanner
5 saw
6 screwdriver

Table LinkProjectTool:
IDProject IDTool
0 0
0 3
2 1
2 4
2 5


The result should be:



ID Name Client ProjectTools
0 table Anna hammer, scissors
1 chair Bobby
2 workbench James measuring tape, spanner, saw
3 window Jenny
4 shelves Matthew


Here are the queries I used to create these tables:



CREATE TABLE [dbo].[Project]
(
[ID] [int] NOT NULL,
[Name] [nvarchar](15) NOT NULL,
[Client] [nvarchar](15) NULL
)

INSERT INTO [dbo].[Project]
(ID, Name, Client)
VALUES
(0, 'table', 'Anna'),
(1, 'chair', 'Bobby'),
(2, 'workbench', 'James'),
(3, 'window', 'Jenny'),
(4, 'shelves', 'Matthew')

CREATE TABLE [dbo].[Tool](
[ID] [tinyint] IDENTITY(0,1) NOT NULL,
[Name] [nvarchar](30) NULL,
CONSTRAINT [PK_Tool] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO [dbo].Tool
(Name)
VALUES
('hammer'),
('measuring tape'),
('pliers'),
('scissors'),
('spanner'),
('saw'),
('screwdriver')

CREATE TABLE [dbo].LinkProjectTool
(
[IDProject] [int] NOT NULL,
[IDTool] [tinyint] NULL
)

INSERT INTO [dbo].LinkProjectTool
(IDProject, IDTool)
VALUES
(0, 0),
(0, 3),
(2, 1),
(2, 4),
(2, 5)


Could you, please, help?



Thank you.










share|improve this question
















This question already has an answer here:



  • How to make a query with group_concat in sql server [duplicate]

    4 answers



There are 3 tables:



  1. Project

  2. Tool

  3. LinkProjectTool

I need a query that lists everything in the Project table plus an extra column called ProjectTools. This column should contain a comma delimited string with all the tool names belonging to each project.



The data is:



Table Project:
ID Name Client
0 table Anna
1 chair Bobby
2 workbench James
3 window Jenny
4 shelves Matthew

Table Tool:
ID Name
0 hammer
1 measuring tape
2 pliers
3 scissors
4 spanner
5 saw
6 screwdriver

Table LinkProjectTool:
IDProject IDTool
0 0
0 3
2 1
2 4
2 5


The result should be:



ID Name Client ProjectTools
0 table Anna hammer, scissors
1 chair Bobby
2 workbench James measuring tape, spanner, saw
3 window Jenny
4 shelves Matthew


Here are the queries I used to create these tables:



CREATE TABLE [dbo].[Project]
(
[ID] [int] NOT NULL,
[Name] [nvarchar](15) NOT NULL,
[Client] [nvarchar](15) NULL
)

INSERT INTO [dbo].[Project]
(ID, Name, Client)
VALUES
(0, 'table', 'Anna'),
(1, 'chair', 'Bobby'),
(2, 'workbench', 'James'),
(3, 'window', 'Jenny'),
(4, 'shelves', 'Matthew')

CREATE TABLE [dbo].[Tool](
[ID] [tinyint] IDENTITY(0,1) NOT NULL,
[Name] [nvarchar](30) NULL,
CONSTRAINT [PK_Tool] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO [dbo].Tool
(Name)
VALUES
('hammer'),
('measuring tape'),
('pliers'),
('scissors'),
('spanner'),
('saw'),
('screwdriver')

CREATE TABLE [dbo].LinkProjectTool
(
[IDProject] [int] NOT NULL,
[IDTool] [tinyint] NULL
)

INSERT INTO [dbo].LinkProjectTool
(IDProject, IDTool)
VALUES
(0, 0),
(0, 3),
(2, 1),
(2, 4),
(2, 5)


Could you, please, help?



Thank you.





This question already has an answer here:



  • How to make a query with group_concat in sql server [duplicate]

    4 answers







sql sql-server tsql many-to-many concatenation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 15:13









Barbaros Özhan

10.8k71430




10.8k71430










asked Nov 10 at 15:03









Ioan

82




82




marked as duplicate by Shnugo sql
Users with the  sql badge can single-handedly close sql questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 11 at 9:55


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Shnugo sql
Users with the  sql badge can single-handedly close sql questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Nov 11 at 9:55


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
    – Shnugo
    Nov 11 at 9:56
















  • There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
    – Shnugo
    Nov 11 at 9:56















There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
– Shnugo
Nov 11 at 9:56




There are tons of examples around. But - seeing your elaborated Minimal, Complete, and Verifiable example - I assume, that you've invested quite some time already. +1 from my side for the question...
– Shnugo
Nov 11 at 9:56












1 Answer
1






active

oldest

votes

















up vote
0
down vote













You can use STUFF function.



Assuming you want the project tools to be separated by a comma and a blank space, you can use the following query:



SELECT DISTINCT p.ID, p.Name, p.Client,
ProjectTools = STUFF((
SELECT ', ' + t.Name
FROM Tool t
WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID





share|improve this answer




















  • Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
    – Shnugo
    Nov 11 at 9:59

















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













You can use STUFF function.



Assuming you want the project tools to be separated by a comma and a blank space, you can use the following query:



SELECT DISTINCT p.ID, p.Name, p.Client,
ProjectTools = STUFF((
SELECT ', ' + t.Name
FROM Tool t
WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID





share|improve this answer




















  • Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
    – Shnugo
    Nov 11 at 9:59














up vote
0
down vote













You can use STUFF function.



Assuming you want the project tools to be separated by a comma and a blank space, you can use the following query:



SELECT DISTINCT p.ID, p.Name, p.Client,
ProjectTools = STUFF((
SELECT ', ' + t.Name
FROM Tool t
WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID





share|improve this answer




















  • Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
    – Shnugo
    Nov 11 at 9:59












up vote
0
down vote










up vote
0
down vote









You can use STUFF function.



Assuming you want the project tools to be separated by a comma and a blank space, you can use the following query:



SELECT DISTINCT p.ID, p.Name, p.Client,
ProjectTools = STUFF((
SELECT ', ' + t.Name
FROM Tool t
WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID





share|improve this answer












You can use STUFF function.



Assuming you want the project tools to be separated by a comma and a blank space, you can use the following query:



SELECT DISTINCT p.ID, p.Name, p.Client,
ProjectTools = STUFF((
SELECT ', ' + t.Name
FROM Tool t
WHERE t.ID IN (SELECT IDTool FROM LinkProjectTool WHERE IdProject = p.ID)
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM Project p LEFT OUTER JOIN LinkProjectTool lpt ON p.Id = lpt.IDProject
ORDER BY p.ID






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 10 at 15:37









Antonio Alvarez

10214




10214











  • Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
    – Shnugo
    Nov 11 at 9:59
















  • Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
    – Shnugo
    Nov 11 at 9:59















Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
– Shnugo
Nov 11 at 9:59




Although this answer is okay, it is 1) a duplicate and more important: 2) You really should understand your own code. STUFF() has nothing to do with the grouped conactenation here. This is provided by the sub-select with FOR XML PATH. This function STUFF() has no other meaning, than to cut away the leading comma + blank...
– Shnugo
Nov 11 at 9:59



這個網誌中的熱門文章

Barbados

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3