Múltiples resultados para un campo en una consulta SQL incorporado
-
23-09-2019 - |
Pregunta
No estoy seguro si esto es posible a partir de una consulta SQL, pero voy a darle una oportunidad.
Estoy desarrollando una parte web de SharePoint en C # que se conecta a una base de datos SQL y ejecuta una consulta, a continuación, que databinds conjunto de resultados a un gridview. Está funcionando bien, pero tengo una pequeña pega. En su mayor parte, mi consulta devolverá exactamente un resultado para cada campo. Estoy mostrando la información verticalmente, por lo que se ve más o menos así:
Customer Name Mr. Customer
Customer Address 980 Whatever St.
Customer City Tallahassee
Todo lo muestra bien. Sin embargo, una de las tablas de la base de datos casi siempre devolver varios resultados. En él se enumeran los diferentes tipos de materiales utilizados para los diferentes productos, por lo que el esquema es diferente porque mientras cada cliente, obviamente, tendrá un nombre, una dirección, una ciudad, etc., todos ellos tendrán al menos un producto, y que el producto tendrá por lo un material menos. Si tuviera que mostrar esa información por sí sola, se vería algo como esto:
Product Steel Type Wood Type Paper Type
-----------------------------------------------------------------------------
Widget Thick Oak Bond
Whatsit Thin Birch
Thingamabob Oak Cardstock
Lo ideal sería, supongo que el resultado final sería algo como:
Customer Name Mr. Customer
Customer Address 980 Whatever St.
Customer City Tallahassee
Widget Steel Thick
Widget Wood Oak
Widget Paper Bond
Whatsit Steel Thin
Whatsit Wood Birch
Thingamabob Wood Oak
Thingamabob Paper Cardstock
Otro resultado aceptable podría ser algo como lo siguiente, añadiendo unas columnas pero sólo devolver varios resultados de esos campos:
Customer Name Mr. Customer
Customer Address 980 Whatever St.
Customer City Tallahassee
Product Steel Type Wood Type Paper Type
Widget Thick Oak Bond
Whatsit Thin Birch
Thingamabob Oak
Estoy abierto a cualquier sugerencia. Me gustaría incluir en el conjunto de resultados sin una consulta independiente, si eso es posible. Aquí está el código que estoy usando para tirar en los datos:
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds, "Specs");
DataSet flipped_ds = FlipDataSet(ds);
DataView dv = flipped_ds.Tables[0].DefaultView;
GridView outputGrid = new GridView();
outputGrid.ShowHeader = false;
outputGrid.DataSource = dv;
outputGrid.DataBind();
Controls.Add(outputGrid);
Me enumeraría mi consulta SQL, pero es enorme. Estoy tirando en más de cien campos en este momento, con una gran cantidad de una subcadena formato y la concatenación, por lo que sería un desperdicio de espacio, pero en realidad es bastante simple una consulta donde estoy seleccionando los campos con la declaración de obtener el nombres que yo quiero, y el uso de unos pocos dejados JOINs para tirar en la necesidad de datos que sin varias consultas. El esquema de la tabla de producto / material es algo como esto:
fldMachineID
fldProductType
fldSteel
fldWood
fldPaper
Así que, obviamente, cada cliente tiene un número de entradas, una para cada valor fldProductType diferente. Si estoy dejando algo fuera, puedo añadirlo. Gracias por el tiempo de todos y ayuda!
Solución
intente lo siguiente:
DECLARE @TableA table (RowID int, Value1 varchar(5), Value2 varchar(5))
DECLARE @TableB table (RowID int, TypeOf varchar(10))
INSERT INTO @TableA VALUES (1,'aaaaa','A')
INSERT INTO @TableA VALUES (2,'bbbbb','B')
INSERT INTO @TableA VALUES (3,'ccccc','C')
INSERT INTO @TableB VALUES (1,'wood')
INSERT INTO @TableB VALUES (2,'wood')
INSERT INTO @TableB VALUES (2,'steel')
INSERT INTO @TableB VALUES (2,'rock')
INSERT INTO @TableB VALUES (3,'plastic')
INSERT INTO @TableB VALUES (3,'paper')
;WITH Combined AS
(
SELECT
a.RowID,a.Value1,a.Value2,b.TypeOf
FROM @TableA a
LEFT OUTER JOIN @TableB b ON a.RowID=b.RowID
)
SELECT
a.*,dt.CombinedValue
FROM @TableA a
LEFT OUTER JOIN (SELECT
c1.RowID
,STUFF(
(SELECT
', ' + TypeOf
FROM Combined c2
WHERE c2.rowid=c1.rowid
ORDER BY c1.RowID, TypeOf
FOR XML PATH('')
)
,1,2, ''
) AS CombinedValue
FROM Combined c1
GROUP BY RowID
) dt ON a.RowID=dt.RowID
Salida:
RowID Value1 Value2 CombinedValue
----------- ------ ------ ------------------
1 aaaaa A wood
2 bbbbb B rock, steel, wood
3 ccccc C paper, plastic
Otros consejos
"Flipping" conjunto de datos se puede hacer en SQL, por ejemplo, véase h @@ p: //stackoverflow.com/questions/2344590/how-do-i-transform-rows-into-columns-in-sql-server -2005 Pero estoy de acuerdo que muchas veces es más fácil de hacer esto en C #
Lo que sugiere KM se expande en este artículo: http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/