2016-05-06 8 views
0

Hier ist meine Abfrage. Ich versuche, eine Tabelle mit einer definierten Tabelle zu verbinden. Aber das Problem ist, wenn wir versuchen, Linke beizutreten, es wirkt wie innerer Join.Mysql Join Problem mit selbst definierten Tabelle

SELECT A.*,B.*, 
(CASE WHEN A.preday != '' THEN 'A' ELSE 'P' END) AS PreStat 
FROM (
    SELECT '2016-05-04' AS preday 
    UNION 
    SELECT '2016-05-03' 
    UNION 
    SELECT '2016-05-02' 
) AS A 
LEFT JOIN `student_attendence` AS B ON B.date = A.preday 
WHERE student_id='1' ; 

Zum Beispiel in der rechten Tabelle nicht ein Datumsfeld mit dem Wert ‚2016.05.02‘ enthalten, aber wenn wir es versuchen, beitreten linke Seite mit NULL-Werte ..aber kommen sollte, wird es nicht Kommen Sie.

meine rechte beitreten Tabellenstruktur ist enter image description here

Bitte helfen Sie mir, es zu lösen.

+0

Was bedeutet "selbst definiert" hier? Bitte, wenn immer möglich, den ** Text ** von 'SHOW CREATE TABLE' anstelle eines Bildes posten. – tadman

+0

ändere das 'where student_ID = '1'' in' as student_ID =' 1'', also ist es Teil des Joins anstelle des Where. Auf diese Weise wird das Limit vor dem Join angewendet, und die durch den Join erstellten Nullsätze bleiben erhalten. – xQbert

+0

@tadman, das bedeutet, dass die Daten der linken Tabelle entsprechend den Umständen dynamisch definiert werden. –

Antwort

1

Denken Sie eine Sekunde darüber nach. Student_ID existiert nur in der Tabelle student_Attendence (für diese 2 Tabellen). Ein Student kann keinen Datensatz für diesen bestimmten Tag haben (muss der Fall sein, wenn Sie nicht 02 in den Ergebnissen bekommen; zumindest für Student 1) Wenn Sie alle Tage von Ihrer abgeleiteten Vereinigungstabelle wollen; dann müssen Sie students_ID filtern, bevor das eintritt, so dass die unerreichte Tag für Rekord Student 1 beitreten wird von links erhalten

SELECT A.*,B.*, (CASE WHEN A.preday != '' THEN 'A' ELSE 'P' END) AS PreStat 
FROM (SELECT '2016-05-04' AS preday 
     UNION SELECT '2016-05-03' 
     UNION SELECT '2016-05-02') AS A 
LEFT JOIN `student_attendence` AS B 
    ON B.date = A.preday 
    and student_id='1' ; 

Student_Attendance registrieren STUDENT_ID 1 wäre ...

ID Date 
1 2016-05-05 
1 2016-05-04 
1 2016-05-03 
1 2016-05-01 

So ist die linke kommen würde zur Folge haben ...

Preday   ID Date     
2016-05-04   1 2016-05-04 
2016-05-03   1 2016-05-03 
2016-05-02   

und wenn Sie die where-Klausel anwenden ... seit 2016.05.02 hat keinen Eintrag für Student 1, wird es beseitigt ..

Aber wenn Sie die WHERE-Klausel in den Join verschieben ... erhalten Sie dies, da der Filter vor dem Join angewendet wird und somit das 02-Datum beibehalten wird.

Preday   ID Date     
2016-05-04   1 2016-05-04 
2016-05-03   1 2016-05-03 
2016-05-02   
+0

Danke @xQbert .. Es funktioniert gut .. –

+0

Immer wenn Sie eine äußere Verbindung verwenden. Die Begrenzungen für Where-Klausel können nur für die Tabelle gelten, in der alle Datensätze zurückgegeben werden. Wenn Sie alle Datensätze beibehalten möchten, erhalten Sie andernfalls ein INNER-Join-Ergebnis, wie Sie gesehen haben. – xQbert

0

der Grund, wegen der logischen Abfrageverarbeitung der Abfrage als die erste Klausel ist das von Klausel ausgeführt werden dann in der> Gruppierung> mit> auswählen>, um durch

so, wenn Sie Ihre eigenen ausführen Abfrage der ersten auszuführenden Klausel ist das, von dem "2016-05-02" mit Null wie erwartet mit dem linken Join zurückgegeben wurde, aber die Where-Klausel filtert danach die Ergebnismenge und entfernt sie, weil die Null unbekannt ist (sie ist nicht t ein Wert, es steht für fehlenden Wert)

so können Sie etwas wie ersetzen, wo cl Ärger mit und Betreiber.