web-dev-qa-db-fra.com

Ms Access Query: Concaténation de lignes via une requête

Supposons que j'ai une table dans MS Access avec les informations suivantes:

ColumnA ColumnB
1       abc
1       pqr
1       xyz
2       efg
2       hij
3       asd

Ma question est la suivante: comment concaténer les valeurs de la deuxième colonne en une valeur de ligne basée sur la première colonne. Les résultats de la requête que je souhaite sont les suivants:

ColumnA ColumnB
1       abc, pqr, xyz
2       efg, hij
3       asd

Je veux y parvenir par une requête. Est-ce que quelqu'un peut m'aider à atteindre ceci?

21
reggie

Vous avez besoin d'une fonction pour effectuer la concaténation.

Microsoft Access condenser plusieurs lignes dans un tableau

Exemple utilisant vos données:

Select T.ColumnA
  , GetList("Select ColumnB From Table1 As T1 Where T1.ColumnA = " & [T].[ColumnA],"",", ") AS ColumnBItems
From Table1 AS T
Group By T.ColumnA;
20
Thomas

Voici un lien remarquable concernant comment procéder à partir de SQL en appelant une fonction. Les instructions sont exceptionnellement claires et la fonction est écrite pour que vous puissiez simplement copier, coller et partir. Même les personnes qui ne connaissent pas VB peuvent facilement l'implémenter: Concaténer les valeurs des enregistrements associés

5
Deborah Cole

cela peut être très difficile à obtenir. Si vous DEVEZ le faire dans une requête et non dans une fonction, le problème que vous allez rencontrer est la limite du nombre de lignes que vous pouvez concaténer dans une colonne. Jusqu'ici, le seul moyen que j'ai trouvé pour atteindre cet objectif est d'utiliser des déclarations iif.

SELECT 
test1.ColumnA AS ColumnA, 
First([test1].[ColumnB]) & IIf(Count([test1].[ColumnB])>1,"," & Last([test1].[ColumnB])) AS ColumnB
FROM test1
GROUP BY test1.ColumnA;

résultats:

ColumnA  ColumnB 
1      abc,xyz 
2      efg,hij 
3      asd

Cela renverra le premier et le dernier seulement, mais je suis sûr qu'avec un peu de travail, vous pourriez travailler avec la fonction Choisir, mais comme je l'ai dit, vous devrez ajouter plus d'instructions iif pour chaque élément supplémentaire que vous souhaitez ajouter. limitation.

2
Patrick

La table peut avoir une colonne de séquence, ce qui lui donne une clé primaire unique de ColumnA-sequence:

table: t1
ColumnA sequence ColumnB
1       1        abc
1       2        pqr
1       3        xyz
2       1        efg
2       2        hij
3       1        asd

Et un tableau croisé pourrait être créé:

query: x1
TRANSFORM Min([columnB] & ", ") AS Expr1
SELECT t1.columnA
FROM t1
GROUP BY t1.columnA
PIVOT t1.sequence;

columnA 1    2    3
1       abc, pqr, xyz,
2       efg, hij,
3       asd,

Ensuite, une dernière requête peut combiner les colonnes et supprimer la dernière virgule:

SELECT x1.columnA, Left([1] & [2] & [3],Len([1] & [2] & [3])-2) AS columnB FROM x1;

columnA columnB
1       abc, pqr, xyz
2       efg, hij
3       asd

Pour automatiser le remplissage de la séquence, le code VBA suivant peut être utilisé:

Sub fill_sequence_t1()
  Dim i: i = 1
  Do While DCount("*", "t1", "sequence IS NULL") > 0
    DoCmd.RunSQL "SELECT t1.columnA, Min(t1.columnB) AS columnB_min INTO t2" & _
                 " FROM t1 WHERE t1.sequence IS NULL GROUP BY t1.columnA;"
    DoCmd.RunSQL "UPDATE t1 INNER JOIN t2 ON (t1.columnA = t2.columnA)" & _
                 " AND (t1.columnB = t2.columnB_min) SET t1.sequence=" & i
    CurrentDb.TableDefs.Delete "t2"
    i = i + 1
  Loop
End Sub
1
Will