将子查询中的多个结果合并为一个逗号分隔的值
时间:2020-03-06 14:30:32 来源:igfitidea点击:
我有两个桌子:
TableA ------ ID, Name TableB ------ ID, SomeColumn, TableA_ID (FK for TableA)
该关系是" TableA"的一行,而" TableB"很多。
现在,我想看到这样的结果:
ID Name SomeColumn 1. ABC X, Y, Z (these are three different rows) 2. MNO R, S
这将不起作用(在子查询中有多个结果):
SELECT ID, Name, (SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID) FROM TableA
如果我在客户端进行处理,这将是一个小问题。但这意味着我将不得不在每个页面上运行X个查询,其中X是" TableA"的结果数。
请注意,我不能简单地执行GROUP BY或者类似的操作,因为它将为TableA的行返回多个结果。
我不确定使用COALESCE或者类似方法的UDF是否可以工作?
解决方案
我认为我们在COALESCE方面步入正轨。有关构建逗号分隔的字符串的示例,请参见此处:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
我们可能需要提供更多详细信息,以进行更精确的响应。
由于数据集似乎有点狭窄,因此我们可以考虑仅对每个结果使用一行,然后在客户端执行后处理。
因此,如果我们真的想让服务器来工作,则返回一个结果集,例如
ID Name SomeColumn 1 ABC X 1 ABC Y 1 ABC Z 2 MNO R 2 MNO S
哪个当然是ID上的简单INNER JOIN
将结果集返回到客户端后,请维护一个名为CurrentName的变量,并在停止将SomeColumn收集到所需的有用操作中时将其用作触发器。
在MySQL中,有一个group_concat函数将返回我们要的内容。
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn) as SomColumnGroup FROM TableA LEFT JOIN TableB ON TableB.TableA_ID = TableA.ID
假设我们在表A上只有WHERE子句,请创建一个存储过程,从而:
SELECT Id, Name From tableA WHERE ... SELECT tableA.Id AS ParentId, Somecolumn FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id WHERE ...
然后用它填充一个DataSet ds。然后
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
最后,我们可以在页面中添加一个中继器,该中继器将每行的逗号放在
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId" DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1" RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top" runat="server" >
这样,我们将在客户端执行此操作,但只需执行一次查询,即可在数据库和前端之间传递最少的数据
1.创建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.在子查询中使用:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3.如果我们使用的是存储过程,则可以执行以下操作:
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
解决方案如下:
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
使用此功能,我们还可以更改联接
即使这样也可以达到目的
样本数据
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'
询问:
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
输出:
ID Name SomeColumn 1 ABC X,Y,Z 2 MNO R,S