2014-08-28 13 views
5

Ho tre tabelle come questo:SQL concatenazione molti a molti

Articoli:

enter image description here

Categorie

enter image description here

e un semplice tavolo MtM per collegarli

enter image description here

Per scopi di reporting, mi sono chiesto se fosse possibile creare un campo con la concatenazione di tutte le categorie a cui appartiene l'elemento. Ad esempio, se ID articolo = 1 appartiene alle categorie ID = 1 e ID = 2; Potrei fare una selezione su Articoli e ottenere un campo 'Categorie' con il valore 'Schuhe; Hemde '

Questo è possibile con SQL da solo a tutti?

il meglio che potevo venire con

SELECT Items.*, Categories.CategoryName 
FROM (CategoryItemAffinities 
     INNER JOIN Categories ON CategoryItemAffinities.CategoryID = Categories.ID) 
INNER JOIN Items ON CategoryItemAffinities.ItemID = Items.ID; 

Ma questo produce, ovviamente, più di un risultato per articolo

[modifica] Proprio per specificare, l'accesso ms è semplicemente il motore di db, ho Non sto usando moduli di accesso/report ecc di per sé. Ho bisogno di questo per un'app C#

+0

"righe concatenare con FOR XML PATH" Google –

+0

@TabAlleman: Che non volerà in MS Access – Andomar

+0

@Andomar ero pieno di speranza fino a quando ho visto il tuo commento: - (solo la query che volevo http://sqlandme.com/2011/04/27/tsql-concatenate-rows-using-for-xml-path/ – Robus

risposta

0

È possibile scorrere un set di record con codice per ottenere i risultati che si cercano, ma che richiederebbero VBA o C#. Accesso non supporta CTE come SQL Server, in modo che rimuova un'altra opzione molto carina. Potrebbe essere possibile utilizzare una tabella pivot e concatenare i campi risultanti. Sarebbe difficile ma credo che potrebbe essere fatto.

creare una query a campi incrociati come tale ...

TRANSFORM First(Categories.CategoryNar) AS FirstOfCategoryNar 
SELECT MtM.ItemID 
FROM Categories INNER JOIN MtM ON Categories.ID = MtM.CategoryID 
GROUP BY MtM.ItemID 
PIVOT MtM.CategoryID; 

quindi creare una query basata sulla query a campi incrociati come questo ...

SELECT Crosstab.ItemID, [1] & [2] & [3] AS ConcatField 
FROM Crosstab; 

I numeri sono CategoryIDs.

enter image description here

Spero che questo aiuta.

1

Jet DB non contiene una funzione di aggregazione per la concatenazione di stringhe. Puoi creare la tua funzione per fare ciò che ti serve.In primo luogo, si desidera che i dati con l'itemID e il valore stringa della categoria, come ad esempio:

yourTableOrQueryName

DAta

quindi scrivere una funzione personalizzata in questo modo:

Public Function getCats(theID) 
    Dim rs As Recordset 
    Dim db As Database 
    Dim qstr As String 
    Dim returnString As String 

    qstr = "SELECT category FROM yourTableOrQueryName WHERE itemID = " & theID 

    Set db = CurrentDb 
    Set rs = db.OpenRecordset(qstr) 

    Do While Not rs.EOF 
     returnString = returnString & ", " & rs!Category 
     rs.MoveNext 
    Loop 

    getCats = Mid(returnString, 3, Len(returnString) - 2) 

End Function 

Quindi la query è la seguente:

SELECT itemID, getCats([itemID]) AS catList 
FROM yourTableOrQueryName 
GROUP BY itemID; 

Quella query può essere ottimizzata in modo che non venga eseguita più volte per ciascun ID nidificando una query univoca selezionata che ottiene gli ID univoci prima di eseguire la funzione "getCats()", se si esegue il trimming di milli secondi, ma te lo lascio.

Risultati:

resuklts