2017-07-03 6 views
-1

Ich habe die folgende SQL wählen:Mehrere LEFT JOIN in mehreren Tabellen

SELECT s.*, 
     GROUP_CONCAT(CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia, 
     GROUP_CONCAT(CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 
FROM sections s 


LEFT JOIN sections_multimedia sm 
    ON s.id = sm.section_id 
LEFT JOIN multimedia m 
    ON sm.multimedia_id = m.id 


LEFT JOIN sections_categories sc 
    ON s.id = sc.section_id 
LEFT JOIN categories c 
    ON sc.category_id = c.id 


WHERE s.id = s.id 
GROUP BY s.id 
ORDER BY s.position, s.id ASC; 

Als Ergebnis das Feld ‚Kategorien‘ hat die richtigen Werte, die (2,3), aber leider oft wiederholt ! (das Ergebnis ist: 2,2,2,2,2,2,3,3,3,3,3,3)

Was ist los mit meiner Auswahl?

Vielen Dank für Ihre Antworten!

+1

Ihr Titel sagt innere schließt sich aber Ihre Abfrage wird mit der linken verbindet? – dbajtr

+0

Mein Fehler! Ich habe den Titel bearbeitet! Vielen Dank! – Nick

+0

Was machen Sie mit diesem Ergebnis? – Strawberry

Antwort

3

Wenn für Aggregate aus verschiedenen Tabellen suchen, sollten Sie immer Aggregat vor dem Beitritt:

SELECT 
    s.*, 
    mul.multimedia, 
    cat.categories 
FROM sections s 
LEFT JOIN 
(
    SELECT 
    sm.section_id, 
    GROUP_CONCAT(CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia 
    FROM sections_multimedia sm 
    JOIN multimedia m ON sm.multimedia_id = m.id 
    GROUP BY sm.section_id 
) mul ON s.id = mul.section_id 
LEFT JOIN 
(
    SELECT 
    sc.section_id, 
    GROUP_CONCAT(CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 
    FROM sections_categories sc 
    JOIN categories c ON sc.category_id = c.id 
    GROUP BY sc.section_id 
) cat ON s.id = cat.section_id; 
+0

Diese Abfrage scheint besser zu funktionieren als die Antwort des Gordon, die auch richtig ist! Aber ist das die schnellste Abfrage, die ich machen könnte, um das Ergebnis zu haben? Alles, was ich erreichen möchte, ist die Auswahl aller "Sektionen" mit allen Multimedia- und Kategorien, denen sie angehören! Was ist die schnellste Abfrage, die ich ausführen könnte? Denn stell dir vor, ich hätte 1.000.000 Zeilen! Vielen Dank! – Nick

+0

@Nick. . . Was schneller ist, hängt von vielen Faktoren bezüglich Ihrer Daten und davon ab, ob Sie zusätzliche Filterung haben. –

+0

Ohne zusätzliche Filterung und wie ist es jetzt, was ist der schnellste Weg zu wählen? – Nick

2

können Sie eindeutige Werte erhalten, indem DISTINCT mit:

SELECT s.*, 
     GROUP_CONCAT(DISTINCT CONCAT_WS(':', m.type, m.id, m.filename) SEPARATOR ',') AS multimedia, 
     GROUP_CONCAT(DISTINCT CONCAT_WS(':', c.id) SEPARATOR ',') AS categories 

Dies ist tatsächlich eine Behelfslösung. Ihr echtes Problem besteht darin, dass mehrere Joins ein kartesisches Produkt mit Wert für jede Zeile in der Ergebnismenge erstellen. Es ist möglicherweise besser, vor dem Herstellen der Joins zu aggregieren, anstatt die Duplikate beim Aggregieren zu entfernen.

+0

Lieber Gordon, danke für deine schnelle Antwort! Wie kann ich agieren, bevor ich die Joins mache? – Nick

+0

Oh, ich habe das gelesen, nachdem ich meine Antwort gepostet habe. Also halten Gordon und ich die gleiche Meinung: Aggregieren vor dem Beitritt :-) –