85

我有两张桌子:

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 是否可行?

4

10 回答 10

137

即使这样也能达到目的

样本数据

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
于 2009-12-21T14:09:12.347 回答
45

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
于 2008-09-21T17:02:14.943 回答
13

在 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
于 2008-09-21T16:30:31.743 回答
11

我认为你在 COALESCE 的道路上是正确的。有关构建逗号分隔字符串的示例,请参见此处:

http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string

于 2008-09-21T16:22:19.407 回答
0

您可能需要提供更多详细信息以获得更准确的响应。

由于您的数据集似乎有点窄,您可能会考虑仅对每个结果使用一行并在客户端执行后处理。

因此,如果您真的想让服务器完成工作,则返回一个结果集,例如

ID       Name       SomeColumn
1        ABC        X
1        ABC        Y
1        ABC        Z
2        MNO        R
2        MNO        S

这当然是 ID 上的简单 INNER JOIN

在客户端返回结果集后,维护一个名为 CurrentName 的变量,并在停止将 SomeColumn 收集到您希望它执行的有用操作时将其用作触发器。

于 2008-09-21T16:26:41.720 回答
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" >

通过这种方式,您将在客户端执行此操作,但只有一个查询,在数据库和前端之间传递最少的数据

于 2008-09-21T16:42:41.637 回答
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
于 2016-06-24T00:06:42.323 回答
-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

使用这个,你也可以改变 Joins

于 2009-12-21T11:59:37.290 回答
-1

我已经查看了所有答案。我认为在数据库插入中应该是这样的:

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

逗号应该在前一个结尾,并通过like进行搜索%,X,%

于 2012-02-14T12:58:45.920 回答
-1
SELECT t.ID, 
       t.NAME, 
       (SELECT t1.SOMECOLUMN 
        FROM   TABLEB t1 
        WHERE  t1.F_ID = T.TABLEA.ID) 
FROM   TABLEA t; 

这将适用于使用子查询从不同的表中进行选择。

于 2012-05-01T16:22:31.850 回答