2011-04-01 42 views
17

Supongamos que tengo tabla en MS Access con el siguiente información:MS Access Pregunta: La concatenación de filas a través de una consulta

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

Mi pregunta es, ¿cómo puedo concatenar los valores de la segunda columna a un valor de fila basan en la primera columna Los resultados de la consulta que quiero es el siguiente:

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

Quiero lograr esto a través de una consulta. ¿Alguien puede ayudarme a lograr esto?

+1

1) Standard SQL no tiene 'Concat' función de conjunto: ¿cuál sería el tipo de datos resultante ser? ¿Violaría 1NF? sería un set? ¿cómo se podrían consultar esos datos? etc .; 2) Access2007 introdujo tipos de múltiples valores (http://www.theregister.co.uk/2006/07/18/multivalued_datatypes_access/print.html); 3) ¿Has considerado un informe? El que se envía con Access es bastante agradable. – onedaywhen

Respuesta

17

Necesita una función para realizar la concatenación.

Microsoft Access condense multiple lines in a table

Ejemplo usando sus datos:

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

Necesito lograr esto en una consulta y no en una función vba. Lo dije en mi pregunta. – reggie

+5

Lee ese enlace. Debería crear una función y usar la función en su consulta. No hay forma de hacerlo de otra manera. – Thomas

+1

¿Pero no está de todos modos para hacerlo solo en la consulta? – reggie

2

esto puede ser muy difícil de obtener. Si DEBE hacerlo en una consulta y no en una función, el problema con el que se encontrará es el límite de la cantidad de filas que puede concatenar en una columna. Hasta ahora, la única forma que he encontrado para lograr esto es a través de declaraciones 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; 

devuelve:

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

Esto devolverá la primera y sólo el último, pero estoy seguro que con un poco de trabajo se puede trabajar a cabo la función de elegir, pero como he dicho que tendría para agregar más declaraciones iif para cada elemento adicional que desee agregar, de ahí la limitación.

+0

Sí. Realmente apreciaría si pudieras publicar esa solución para mí. – reggie

+1

@reggie: el problema con la solución anterior es la cantidad desconocida de elementos secundarios. En este momento, cada elemento solo tiene 2 valores de columna B. ¿Qué pasa cuando hay 10? 100? – Thomas

+0

en última instancia ... está determinada por la cantidad de elementos que planea tener ... si el valor de columnA puede tener 20 elementos agrupados en columnB ... probablemente esta no sea su mejor solución ... si mira de 2 a 3 es posible. – Patrick

5

Aquí hay un enlace sobresaliente sobre cómo hacer esto desde SQL llamando a una función. Las instrucciones son excepcionalmente claras & la función está escrita para usted, así que puede simplemente copiar, pegar & ir. Incluso alguien que no tiene conocimiento de VB puede implementar fácilmente: Concatenate values from related records

0

La tabla podría tener una columna de secuencia, lo que le da una clave primaria única de ColumnA-secuencia:

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

Y una tabla cruzada podría ser creado:

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, 

a continuación, una consulta final puede combinar las columnas y retire la última coma:

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 

para automatizar el llenado de la secuencia, el siguiente código de VBA se puede utilizar:

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 
Cuestiones relacionadas