2016-07-13 14 views
1

Ich habe eine Datenbank unter MySQL mit einer Haupttabelle mit eindeutiger ID, einige Tabellen, die verschiedene Auswahlmöglichkeiten (mit einer ID-Spalte, eine Textspalte, um das Element zu beschreiben). Für einen Datensatz in der Haupttabelle können also mehrere Auswahlmöglichkeiten mit der Auswahltabelle verknüpft sein.
Ich möchte eine Ansicht erstellen, in der alle Informationen sichtbar sein können, wobei GROUP_CONCAT verwendet wird, um die verschiedenen Auswahlmöglichkeiten aus einer gegebenen Auswahltabelle in ein Feld zu verketten. Meine Abfrage wiederholt jedoch viele Male jede Auswahlliste, wenn der Datensatz mit anderen Mehrfachauswahlmöglichkeiten aus einer anderen Auswahltabelle verknüpft ist. Die Abfrage gibt alle möglichen Kombinationen zwischen diesen Entscheidungen ...
Hier meine Frage (reduziert auf 2 ‚Wahl‘ Tabellen -t_age, t_animal- für das Beispiel)
Verwenden Sie eine GROUP_CONCAT und JOIN in einer Unterabfrage

SELECT general.id_g, 
    GROUP_CONCAT(CAST(t_age AS CHAR) SEPARATOR ', ') AS age, 
    GROUP_CONCAT(CAST(t_animal AS CHAR) SEPARATOR ', ') AS animal 
FROM general 
LEFT JOIN interm_age 
    INNER JOIN t_age ON interm_age.id_age = t_age.id_age 
ON general.id_g = interm_age.id_g 
LEFT JOIN interm_animal 
    INNER JOIN t_animal ON interm_animal.id_animal = t_animal.id_animal 
ON general.id_g = interm_animal.id_g 
GROUP BY id_g; 

Ich habe versucht, jedes CONCAT aufzunehmen/JOIN innerhalb einer Unterabfrage in einen Haupt-SELECT wie folgt, aber MySQL sagt mir "gibt mehr als 1row zurück", was tatsächlich der Fall ist. Und?

SELECT id_g, (
    SELECT GROUP_CONCAT(CAST(t_age AS CHAR) SEPARATOR ', ') 
    FROM general 
    LEFT JOIN interm_age 
    INNER JOIN t_age ON interm_age.id_age = t_age.id_age 
    ON general.id_g = interm_age.id_g 
    GROUP BY general.id_g ) 
FROM general; 


[EDIT] Genauer gesagt, das ist meine DB ist (mit FK)

allgemeinen
-----------

id_g | date 
902 | 2016/01/01 
956 | 2016/02/01 
959 | 2016/02/01 


interm_age
-------- ---

id_age | id_g 
1  |  902 
3  |  902 
1  |  956 
4  |  956 


interm_animal
-----------

id_animal |  id_g 
1   |  902 
5   |  902 
5   |  959 
7   |  959 


t_age
---------- -

id_age |  age 
1  |  <10y 
3  |  >10y 
4  |  >60y 


t_animal
-----------

id_animal | animal 
1   | bird 
5   |  mammal 
7   |  insect 


und ich möchte so etwas wie:

id_g | date  | age  | animal 
902 | 2016/01/01 | <10y, >10y | bird, mammal 

und so weiter ..

Vielen Dank im Voraus!

Antwort

0

Obwohl es besser wäre, wenn Sie einige Beispieldaten, tatsächliche Ergebnisse und erwartete Ergebnisse zur Verfügung stellen, habe ich einen Stich in der Lösung.

Das Problem ist wahrscheinlich, dass Sie mehrere übereinstimmende Datensätze in den verbundenen Tabellen haben, was zu einer Duplizierung der Werte innerhalb von group_concat() führt.

Wie MySQL-Dokumentation auf group_concat() zeigt an, Sie das Schlüsselwort distinct doppelte Werte entfernen können:

doppelte Werte zu eliminieren, die DISTINCT-Klausel verwenden.

SELECT general.id_g, 
    GROUP_CONCAT(DISTINCT CAST(t_age AS CHAR) SEPARATOR ', ') AS age, 
    GROUP_CONCAT(DISTINCT CAST(t_animal AS CHAR) SEPARATOR ', ') AS animal 
FROM general 
LEFT JOIN interm_age 
    INNER JOIN t_age ON interm_age.id_age = t_age.id_age 
ON general.id_g = interm_age.id_g 
LEFT JOIN interm_animal 
    INNER JOIN t_animal ON interm_animal.id_animal = t_animal.id_animal 
ON general.id_g = interm_animal.id_g 
GROUP BY id_g; 
+0

Vielen Dank für Ihre schnelle Antwort. Leider hilft das Hinzufügen von DISTINCT nicht. Ich habe meine Frage bearbeitet, um mehr Details anzuzeigen. – RemiC

+0

Welche Ausgabe erhalten Sie, wenn Sie das Schlüsselwort distinct verwenden? – Shadow

+0

"Unterabfrage gibt mehr als 1 Zeile zurück", also der gleiche Fehler wie ohne DISTINCT. Ich hatte ein ähnliches Problem mit einer Sub-Abfrage innerhalb der SELECT, und ich löste es mit einer UNION zwischen so vielen Abfragen wie Bedingungen (mit CASE WHEN). Aber hier habe ich keine Bedingung zu füllen. – RemiC

0

dieses, das hilft

SELECT general.id_g, 
    GROUP_CONCAT(CAST(t_age AS CHAR) SEPARATOR ', ') AS age, 
    GROUP_CONCAT(CAST(t_animal AS CHAR) SEPARATOR ', ') AS animal 
FROM general 
LEFT JOIN interm_age 
    INNER JOIN t_age ON interm_age.id_age = t_age.id_age AND general.id_g = interm_age.id_g 
LEFT JOIN interm_animal 
    INNER JOIN t_animal ON interm_animal.id_animal = t_animal.id_animal AND general.id_g = interm_animal.id_g 
GROUP BY id_g; 

Hoffnung Versuchen.

+0

Danke, aber es funktioniert auch nicht. Das zweite ON sollte die Klausel des ersten JOIN angeben. Beachten Sie, dass dieser Teil der Abfrage den Job bisher ausführt. Alternativ hätte ich zwei getrennte LINKE VERBINDUNGEN schreiben können, da es scheint, das gleiche zu tun. – RemiC