我有两张桌子:
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是否有效?
答案 0 :(得分:128)
即使这样也可以达到目的
示例数据
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
答案 1 :(得分:45)
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
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
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
答案 2 :(得分:11)
我认为你与COALESCE走在正确的轨道上。请参阅此处以获取构建逗号分隔字符串的示例:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
答案 3 :(得分:9)
在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
答案 4 :(得分:0)
您可能需要提供更多详细信息才能获得更准确的响应。
由于您的数据集看起来很窄,您可能会考虑在每个结果中使用一行并在客户端执行后处理。
因此,如果您真的想让服务器完成工作,请返回结果集,如
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
当然是ID上的简单INNER JOIN
将结果集返回给客户端后,维护一个名为CurrentName的变量,并将其作为触发器,以便停止将SomeColumn收集到您希望它执行的有用操作中。
答案 5 :(得分:0)
假设您在表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" >
通过这种方式,您可以在客户端进行,但只有一个查询,在数据库和前端之间传递最少的数据
答案 6 :(得分:0)
我尝试了提到的解决方案priyanka.sarkar,并且当OP询问时,它并没有完全正常工作。这是我最终得到的解决方案:
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
答案 7 :(得分:-1)
以下解决方案:
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
使用此功能,您也可以更改联接
答案 8 :(得分:-1)
我已经回顾了所有答案。我认为在数据库插入中应该像:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
逗号应位于上一页,并按照%,X,%
答案 9 :(得分:-1)
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
这将用于使用子查询从不同的表中进行选择。