合并多对多关系联接中的列值

时间:2012-05-11 12:17:18

标签: sql sql-server asp.net-3.5 sql-server-2008-express

我有两个表,图书作者,通过名为 book_authors 的第三个表格与他们之间存在多对多的关系,我我试图使用内部联接为每本书列出作者的所有书籍,以便在DataList控件中显示它们,但是联接导致了几个重复的行,因为每本书可能有很多作者,所以那里每个作者都会排成一行 示例:

book_title           author  
b1                    a1  
b1                    a2  

解决此问题的最佳方法是:

book_title                author  
b1                        a1, a2  

3 个答案:

答案 0 :(得分:4)

也许是这样的:

SELECT
    Books.book_title,
    STUFF
    (
        (
            SELECT 
                ',' +author
            FROM
                book_authors
                JOIN Authors
                    ON book_authors.authorId=Authors.authorId
            WHERE
                book_authors.bookId=Books.bookid
            FOR XML PATH('')
        )
    ,1,1,'')
FROM
    Books

修改

很难说没有你的数据。这有用吗:

DECLARE @Table1 TABLE(ID INT)
DECLARE @Table2 TABLE(Name varchar(100),ID INT)

INSERT INTO @Table1 VALUES(1),(2)
INSERT INTO @Table2 VALUES('test1',1),('test2',1),('test3',2),('test4',2)

SELECT
    t1.ID,
    STUFF
    (
        (
            SELECT 
                ',' +t2.Name
            FROM
                @Table2 AS t2
            WHERE
                t1.ID=t2.ID
            FOR XML PATH('')
        )
    ,1,1,'')
FROM
    @Table1 AS t1

答案 1 :(得分:1)

如果你想纯粹在SQL中这样做,那么你将需要一个子查询,它将书籍id和yeilds作为结果列表(csv,如果这就是你想要它)。在另一个查询中使用该子查询为每个唯一的bookid 它返回book_title和作者列表。

如果你不介意不使用纯SQL,我会说只是遍历你当前获得的DataList,并在你经历时添加作者的地图类型结构(book_title - > authorList)。 / p>

最好的选择取决于你如何使用它的范围,但通常我会说sql路由是要走的路。

答案 2 :(得分:1)

您要做的是字符串聚合连接。关于这个问题,有一些非常好的帖子。

这是一个替代方案,在您的案例中可能很容易,因为书籍没有太多的作者:

select b.name,
       (max(case when authornum = 1 then author else '' end) +
        max(case when authornum = 2 then ', '+ author else '' end) +
        max(case when authornum = 3 then ', '+ author else '' end)
       ) as authors
 from (select ba.*,
              row_number() over (partition by bookid order by authorid) as authornum
       from BookAuthors ba
      ) bajoin
      Authors a
      on a.authorid = ba.authorid join
      Books b
      on b.bookid = ba.bookid
 group by b.name

您只需要确保在select语句中包含足够的作者。