Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple results in a subquery into a single comma-separated value

I've got two tables:

TableA ------ ID, Name  TableB ------ ID, SomeColumn, TableA_ID (FK for TableA) 

The relationship is one row of TableA - many of TableB.

Now, I want to see a result like this:

ID     Name      SomeColumn  1.     ABC       X, Y, Z (these are three different rows) 2.     MNO       R, S 

This won't work (multiple results in a subquery):

SELECT ID,        Name,         (SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID) FROM TableA 

This is a trivial problem if I do the processing on the client side. But this will mean I will have to run X queries on every page, where X is the number of results of TableA.

Note that I can't simply do a GROUP BY or something similar, as it will return multiple results for rows of TableA.

I'm not sure if a UDF, utilizing COALESCE or something similar might work?

like image 755
Donnie Thomas Avatar asked Sep 21 '08 16:09

Donnie Thomas


People also ask

How do I concatenate multiple rows into a single row in SQL Server?

You can concatenate rows into single string using COALESCE method. This COALESCE method can be used in SQL Server version 2008 and higher. All you have to do is, declare a varchar variable and inside the coalesce, concat the variable with comma and the column, then assign the COALESCE to the variable.

How do I return multiple values from a subquery?

Multiple row subquery returns one or more rows to the outer SQL statement. You may use the IN, ANY, or ALL operator in outer query to handle a subquery that returns multiple rows. Contents: Using IN operator with a Multiple Row Subquery.

What if subquery returns multiple rows?

Multiple-row subqueries are nested queries that can return more than one row of results to the parent query. Multiple-row subqueries are used most commonly in WHERE and HAVING clauses. Since it returns multiple rows, it must be handled by set comparison operators (IN, ALL, ANY).


2 Answers

Even this will serve the purpose

Sample data

declare @t table(id int, name varchar(20),somecolumn varchar(MAX)) insert into @t     select 1,'ABC','X' union all     select 1,'ABC','Y' union all     select 1,'ABC','Z' union all     select 2,'MNO','R' union all     select 2,'MNO','S' 

Query:

SELECT ID,Name,     STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))      FROM @T T2 WHERE T1.id = T2.id AND T1.name = T2.name      FOR XML PATH('')),1,1,'') SOMECOLUMN FROM @T T1 GROUP BY id,Name 

Output:

ID  Name    SomeColumn 1   ABC     X,Y,Z 2   MNO     R,S 
like image 168
priyanka.sarkar Avatar answered Sep 22 '22 05:09

priyanka.sarkar


1. Create the UDF:

CREATE FUNCTION CombineValues (     @FK_ID INT -- The foreign key from TableA which is used                 -- to fetch corresponding records ) RETURNS VARCHAR(8000) AS BEGIN DECLARE @SomeColumnList VARCHAR(8000);  SELECT @SomeColumnList =     COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))  FROM TableB C WHERE C.FK_ID = @FK_ID;  RETURN  (     SELECT @SomeColumnList ) END 

2. Use in subquery:

SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA 

3. If you are using stored procedure you can do like this:

CREATE PROCEDURE GetCombinedValues  @FK_ID int As BEGIN DECLARE @SomeColumnList VARCHAR(800) SELECT @SomeColumnList =     COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))  FROM TableB WHERE FK_ID = @FK_ID   Select *, @SomeColumnList as SelectedIds     FROM          TableA     WHERE          FK_ID = @FK_ID  END 
like image 44
6 revs, 4 users 64% Avatar answered Sep 22 '22 05:09

6 revs, 4 users 64%