2014-08-28 21 views
5

Mam trzy tabele tak:SQL Łączenie wiele do wielu

przedmiotów:

enter image description here

Kategorie

enter image description here

i prostą tabelę MtM połączyć je

enter image description here

Dla celów sprawozdawczych zastanawiałem się, czy byłoby możliwe utworzenie pola z konkatenacją wszystkich kategorii, do których należy element. Na przykład, jeśli identyfikator produktu = 1 należałby do kategorii ID = 1 i ID = 2; Mógłbym dokonać wyboru na przedmiotach i uzyskać pole "Kategorie" z wartością "Schuhe; Hemde '

Czy to możliwe z samym SQL?

Najlepszym mogę wymyślić

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

Ale to oczywiście daje więcej niż jeden wynik za sztukę

[edytuj] Wystarczy określić, dostęp ms jest jedynie silnik db, I "Nie używam formularzy dostępu/raportów itp. jako takich. Potrzebuję tego dla aplikacji C#

+0

Google "oddzielając wiersze z FOR XML PATH" –

+0

@TabAlleman: To nie będzie latać w MS Access – Andomar

+0

@Andomar byłem pełen nadziei, dopóki nie zobaczyłem swój komentarz: - (tylko zapytanie, które chciałem http://sqlandme.com/2011/04/27/tsql-concatenate-rows-using-for-xml-path/ – Robus

Odpowiedz

0

Można przechodzić przez zestaw rekordów z kodem, aby uzyskać wyniki, których szukasz, ale to wymagałoby VBA lub C#. Access nie obsługuje CTE jak SQL Server, dzięki czemu usuwa kolejną bardzo dobrą opcję. Może być to możliwe za pomocą tabeli przestawnej i łączenia uzyskanych pól. Byłoby to trudne, ale uważam, że można to zrobić.

Utwórz kwerendę krzyżową jako takie ...

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; 

Następnie należy utworzyć kwerendę opartą na kwerenda krzyżowa jak to ...

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

Liczby są CategoryIDs.

enter image description here

Mam nadzieję, że to pomaga.

1

Jet DB nie zawiera zagregowanej funkcji do łączenia ciągów. Możesz stworzyć własną funkcję, aby robić to, czego potrzebujesz.Po pierwsze, chcesz, aby Twoje dane z itemID a wartością Ciąg kategorii, jako takich:

yourTableOrQueryName

DAta

następnie napisać funkcję niestandardową tak:

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 

Następnie zapytanie wygląda następująco:

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

To zapytanie można zoptymalizować, aby nie było uruchamiane wiele razy dla każdego identyfikatora, zagnieżdżając wybrane unikalne zapytanie, które po prostu otrzyma unikatowe identyfikatory, zanim uruchomisz funkcję "getCats()", jeśli chcesz przyciąć milli secs, ale zostawię to tobie.

Wyniki:

resuklts