2016-05-05 10 views
0

Ich weiß, dass mysql die äußere Tabelle von einer Unterabfrage nicht erkennt, aber leider habe ich keine Ahnung, wie ich das lösen soll.SQL-Abfrage zu mysql (Unterabfrage erkennt äußere Tabelle nicht)

Zuerst wird die Tabellenstruktur, ich habe drei Tabellen (m bis n):

Tabelle 1: Tanz

TID | Name_Of_The_Dance 
12 | Heute Tanz ich 

Table2: Tänzerin

TAID | Name_Of_Dancer 
1 | Alex Womitsch 
2 | Julian Berger 

Tabelle 3 (Referenzierung Tabelle): dance2dancer

TID | TAID 
12 | 213 
12 | 345 

Was muss ich (Ausgang) erreichen wollen:

TID | AllDancerWhoDance 
12 | 213---,345---,0---,0---,0---,0---,0---,0---,0---,0--- 

Jeder Ausgang sollte die Tanz TID haben und alle Tänzer, der in diesem Tanz tanzen. Aber AllDancerWhoDance sollte mit "0 ---" gefüllt sein, wenn wir weniger als 10 Tänzer haben. Wenn wir mehr als 10 Tänzer in diesem Tanz haben, sollte die Abfrage die Saite auf maximal 10 Tänzer reduzieren.

Weitere Beispiele zu unterstand: Ein Tanz mit 4 Tänzer sollte mit 6 Nullen gefüllt werden:

9 | 213---,345---,111---,459---,0---,0---,0---,0---,0---,0--- 

Haben wir einen Tanz mit mehr als 10 Tänzer die Abfrage auf 10 verringern sollte:

9 | 213---,345---,111---,459---,333---,444---,445---,222---,192---,490--- (NO more zeros or dancer TAIDs) 

Und hier ist meine Frage:

select dancer.tid, 
    IF(count(dancer.taid) <= 10, 
     CONCAT_WS("",GROUP_CONCAT(dancer.taid,"&&&"), REPEAT(";0",10-count(dancer.taid))) 
     , (SELECT GROUP_CONCAT(a.taid,"&&&") from (SELECT ttt.taid from dance2dancer ttt inner join dance taenz on ttt.tid = taenz.tid where ttt.tid = dance.tid LIMIT 10) as a) 
    ) AS "AllDancerWhoDance" 
from dance inner join dance2dancer tt on dance.tid = tt.tid inner join dancer on tt.taid = dancer.taid group by dance.tid 

ich denke, es würde funktionieren, aber das Problem ist, dass die Unterabfrage nicht in die äußere Tabelle sieht und das „Wo“ -Klausel funktioniert nicht:
wo ttt.tid = dance.tid

Und jetzt meine Fragen:
Wie kann ich erreichen, dass diese SQL-Abfrage in MySQL funktioniert?

Danke

// UPDATE
Da viele Menschen für die Front-End-Code gefragt und warum sollte ich diese Abfrage benötigen: Wir haben eine 22 Jahre alte Software, die diese Daten in einem solchen Format benötigt . Es wurde von einer Firma programmiert, die es nicht mehr gibt und wir haben keinen Quellcode für dieses Programm. Wir haben die Datenbank und die Website auf dieses neue Datenmodell (m: n) geändert, aber das alte Programm benötigt noch die Daten im alten Format. Daher brauche ich diese seltsame Abfrage. Und ja, wir arbeiten auch an einem neuen Programm.

+0

ich nicht aus einem vernünftigen Grund für die Konstruktion solcher eine ungerade Zeichenfolge denken kann. : - $ – Strawberry

Antwort

0

Der Grund für Ihren Fehler ist, dass Sie nicht auf äußere Spalten innerhalb einer abgeleiteten Tabelle (Ihre from (...) as a) zugreifen können. Um es zu tun, müssen Sie etwas wie (...) as a where a.tid = dancer.tid schreiben, also setzen Sie die where außerhalb der abgeleiteten Tabelle; aber Sie müssen natürlich a in einer Weise umschreiben, tid als eine Spalte zu haben.

In Ihrem Fall wäre es komplizierter sein, Ihren Code zu beheben, so schrieb ich Ihnen ein (einfacher) neue:

select tid, 
    CONCAT_WS("", 
    (SELECT GROUP_CONCAT(d2d2.taid,"---") 
    from dance2dancer d2d2 
    where d2d2.tid = d2d.tid 
    group by d2d2.tid limit 10), 
    REPEAT(",0---",10-count(distinct d2d.taid)) 
) as `AllDancerWhoDance` 
from dance2dancer d2d 
group by d2d.tid 

Und eine Warnung: diese Art der Abfrage (Group_concat oder Concat mit in Eine Spalte) wird nur in einem letzten Schritt zur Formatierung der Daten verwendet, die Sie anzeigen möchten. Wenn Sie vorhaben, es in einer anderen Abfrage zu verwenden, z. etwas wie select * from dancer where INSTR('213---,345---,111---', taid) > 0, bitte nicht, nur umschreiben.

aktualisieren ohne limit 10 mit: nur Concat alles

Obwohl limit 10 mit Group_concat funktionieren sollte (es funktioniert für mich), für den Fall, funktioniert es nicht für Sie arbeiten, können Sie natürlich und dann die erste 10 Einträge der concated Zeichenfolge danach. Es würde tatsächlich die Abfrage vereinfachen, da Sie die Unterabfrage nicht mehr benötigen (die limit an erster Stelle), aber möglicherweise eine große temporäre Zeichenfolge generieren (vor substring_index), wenn Sie einen Tanz mit A LOT haben von Tänzern.

select tid, 
    SUBSTRING_INDEX(CONCAT_WS("", 
    GROUP_CONCAT(d2d.taid,"---"), 
    REPEAT(",0---",10-count(distinct d2d.taid)), 
    ',' 
), ',',10) as `AllDancerWhoDance` 
from dance2dancer d2d 
group by d2d.tid; 

oder eine rownumber berechnen im Voraus und nehmen Sie nur die ersten 10 Reihen pro tid:

select d2d.tid, CONCAT_WS("", 
    GROUP_CONCAT(d2d.taid,"---"), 
    REPEAT(",0---",10-d2d.cnt) 
) as `AllDancerWhoDance` 
from 
(select tid, taid, 
     (select count(*) 
     from dance2dancer d2d4 
     where d2d4.tid = d2d3.tid 
     and d2d4.taid <= d2d3.taid 
    ) as rownum, 
     (select count(*) 
     from dance2dancer d2d4 
     where d2d4.tid = d2d3.tid 
    ) as cnt 
     from dance2dancer d2d3 
) as d2d 
where d2d.rownum <= 10 
group by d2d.tid; 
+0

Vielen Dank für Ihre Antworten. @Solarflare: Die Abfrage ist großartig, es gibt nur ein Problem mit GROUP_CONCAT und Limit. Es funktioniert nicht zusammen. zum Beispiel: http://stackoverflow.com/questions/23608464/group-concat-with-limit Und wenn ich neu schreiben Sie Ihre Anfrage an: wählen tid, CONCAT_WS ("", (SELECT GROUP_CONCAT (a .taid, "---") (wählen Sie d2d.taid von dance2dancer d2d2 wo d2d2.tid = d2d.tid 10) limit), wie a, REPEAT ("0 ---", 10-count (distinct d2d.taid)) ) als 'AllDancerWhoDance' von dance2dancer d2d Gruppe von d2d.tid Und wieder ein Problem mit den äußeren Spalten: -/ –

+0

Was ist Ihre MySQL-Version? 'Limit' funktioniert für mich, aber trotzdem habe ich 2 Versionen ohne' Limit' hinzugefügt. Stellen Sie sicher, dass Sie es wirklich 1: 1 kopieren und einfügen, um Fehler auszuschließen, die beim Umschreiben auftreten können (Ihr umgeschriebener Code, den Sie hier eingefügt haben, fehlt mindestens ein "von"). – Solarflare

+0

Vielen Dank. Die Abfrage funktioniert gut :-) Aber ich frage mich, warum "Limit" auf Ihrer Maschine funktioniert? Da auch Oracle dies nicht behoben hat: http://bugs.mysql.com/bug.php?id=30098 Ich habe diesen Code mit MySQL Version 5.5.46 und 5.5.28 getestet –

0

Um 10 Tänzer für einen bestimmten Tanz dies zu tun:

select D.Name_Of_Dancer 
from dancer DR, dance2dancer DD 
where DD.taid = DR.taid 
groupby DD.tid 
Limit 10 

Sie können auch Desc oder ASC fügen Sie die Liste der Tänzer Liste zu sortieren und die ersten 10 Tänzer extrahieren.

Aber um mindestens 10 Tänzer in einer Liste zu bekommen, auch wenn es nicht existiert. Das ist nicht möglich mit mysql. Was ich meine ist, zeigen Sie mir den Code am Frontend, wie behandeln Sie, was wir tun können, ist die Anzahl der Ergebnisse zu zählen. Wenn die Ergebnisse 4 sind, können wir einfach eine Schleife verwenden, um 6 weitere Einträge zu erzeugen, um insgesamt 10 Tänzer zu erhalten. Aber ich empfehle nicht, sie von mysql Ende zu behandeln. Es ist eine schlechte Übung.

+0

Nicht möglich in gewisser Hinsicht ist es eine schlechte Praxis. Die Idee der Datenbank besteht darin, Datensätze zu speichern, Datensätze abzurufen usw., aber keine leeren Datensätze zu erstellen, ist wirklich eine gute Idee. Warum nicht in der Seite behandeln oder –

+0

ansehen Ah, ich sehe was du meinst. – Strawberry

+0

Ja, also, wenn Sie Ihren Front-End-Code zeigen könnten. Ich könnte eine Hilfe sein. Auch, warum es auf der Front-End-Seite gut ist, dass es nur für die Seite willen ist, dass wir 10 Ergebnisse zeigen wollen und wenn nicht viele vorhanden sind, dann einfach Null oder Null am Frontend hinzufügen. Da es Ihre Anfrage einfach und sauber hält. Und dynamisch zusätzliche Bits am Frontend generieren. –

Verwandte Themen