2012-05-11 5 views
3

j'ai deux tables, Livres et Auteurs, avec plusieurs à plusieurs entre eux par une troisième table appelée book_authors, je suis en train d'énumérer toutes les livres avec les auteurs pour chaque livre en utilisant une jointure interne afin de les afficher dans un contrôle DataList, mais la jointure entraîne plusieurs lignes en double, car chaque livre peut avoir plusieurs auteurs, donc il y aura une ligne pour chaque auteur.
Exemple:fusion des valeurs de colonne dans plusieurs à plusieurs jointures

book_title   author 
b1     a1 
b1     a2 

Quelle est la meilleure façon de résoudre ce problème il devient:

book_title    author 
b1      a1, a2 
+0

Utilisez une sous-requête et une fonction de concaténation de chaîne sur votre base de données, puis indiquez la liste des auteurs comme seule chaîne à afficher. – Gabber

+0

Jetez un oeil à ces messages: http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-ms-sql-server-2005, http://stackoverflow.com/questions/ 273238/comment-utiliser-groupe-par-concaténer-chaînes-dans-sql-server et http://stackoverflow.com/questions/941103/concat-groups-in-sql-server – Marco

Répondre

4

Peut-être quelque chose comme ceci:

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 

EDIT

Il est difficile à dire sans vous da ta. Est-ce que ce travail:

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 
+0

Mis à jour le réponse – Arion

+0

Merci beaucoup, vous m'avez sauvé la vie. J'ai réussi à le faire fonctionner. –

+0

Pas de problème. Heureux d'aider: P – Arion

1

Si vous voulez le faire uniquement dans SQL, vous aurez besoin d'une sous-requête qui prend l'identifiant du livre et yeilds une liste d'auteurs (csv si c'est comme vous le voulez) comme résultat. Utilisez cette sous-requête au sein d'une autre requête pour chaque bookid unique elle renvoie la liste book_title et la liste des auteurs. Si cela ne vous dérange pas de ne pas utiliser le SQL pur, je dirais juste parcourir la liste de données que vous obtenez actuellement et créer une structure de type carte (book_title -> authorList) en ajoutant les auteurs au fur et à mesure.

Le meilleur choix dépend de la portée de votre utilisation, mais en général, je dirais que la route sql est la voie à suivre.

+0

C'est exactement ce que j'allais faire, mais je ne peux pas comprendre la requête SQL pour le faire. –

+1

Je m'excuse de ne pas avoir eu le temps de tout écrire, mais [ICI] (http://blog.sqlauthority.com/2009/11/25/sql-server-comma-separated-values-csv-from-table- column /) est un lien sur la façon de prendre une table et de le transformer en une chaîne csv. Si vous en faites une fonction, vous pouvez l'utiliser dans la requête. Il suffit de passer cette fonction à l'ID du livre, il retournera la chaîne csv, et le faire pour tous les livres.Le post ci-dessous par G. Linoff pourrait aussi fonctionner si vous connaissez le nombre maximum d'auteurs que vous avez. –

1

Ce que vous voulez faire est la concaténation d'agrégat de chaîne. Il y a de très bons posts sur ce sujet.

Voici une alternative, qui pourrait fonctionner facilement dans votre cas, étant donné que les livres ne sont pas trop d'auteurs:

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 

Vous devez simplement être sûr que vous incluez les auteurs assez dans l'instruction select.

+0

merci, je pourrais essayer cela dans le futur si j'avais besoin de, les messages ci-dessus ont bien fonctionné pour le moment. –