sql server - tablas - Combine resultados múltiples en una subconsulta en un solo valor separado por comas
stuff sql server ejemplos (10)
Tengo dos tablas:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
La relación es una fila de TableA
, muchas de TableB
.
Ahora, quiero ver un resultado como este:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
Esto no funcionará (resultados múltiples en una subconsulta):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
Este es un problema trivial si hago el procesamiento en el lado del cliente. Pero esto significará que tendré que ejecutar consultas X en cada página, donde X es el número de resultados de la TableA
Tenga en cuenta que no puedo simplemente hacer un GROUP BY o algo similar, ya que devolverá resultados múltiples para las filas de TableA
.
No estoy seguro si un UDF, utilizando COALESCE o algo similar podría funcionar?
1. Crea el 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. Usar en subconsulta:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. Si está utilizando un procedimiento almacenado, puede hacer esto:
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
Creo que estás en el camino correcto con COALESCE. Vea aquí un ejemplo de construcción de una cadena delimitada por comas:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
En MySQL hay una función group_concat que devolverá lo que está pidiendo.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
Es posible que deba proporcionar más detalles para una respuesta más precisa.
Debido a que su conjunto de datos parece algo limitado, puede considerar usar una fila por resultado y realizar el postproceso en el cliente.
Entonces, si realmente está buscando hacer que el servidor haga el trabajo, devuelva un conjunto de resultados como
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
que por supuesto es un simple INNER JOIN en ID
Una vez que tenga el conjunto de resultados en el cliente, mantenga una variable llamada CurrentName y utilícela como desencadenante cuando deje de recopilar SomeColumn en lo útil que desea que haga.
He revisado todas las respuestas. Creo que en la inserción de la base de datos debería ser como:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
La coma debe estar en el extremo anterior y hacer búsquedas como %,X,%
Incluso esto servirá para el propósito
Data de muestra
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''
Consulta:
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
Salida:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
Intenté con la solución que priyanka.sarkar mencionó y no funcionó del todo, como pidió el OP. Aquí está la solución con la que terminé:
SELECT ID,
SUBSTRING((
SELECT '','' + T2.SomeColumn
FROM @T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('''')), 2, 1000000)
FROM @T T1
GROUP BY ID
Solución a continuación:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
Usa esto, también puedes cambiar las uniones
Suponiendo que solo tiene cláusulas WHERE en la tabla A, cree un procedimiento almacenado así:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Luego llene un DataSet ds con él. Entonces
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Finalmente puede agregar un repetidor en la página que coloca las comas para cada línea
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource=''<%# Container.DataItem.CreateChildView("foo") %>'' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
De esta forma, lo hará desde el lado del cliente, pero con solo una consulta, pasando datos mínimos entre la base de datos y la interfaz
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
Esto funcionará para seleccionar de una tabla diferente mediante una sub consulta.