Vinzenz Mai: MySQL JOIN: Ausgabe von Feld aus Tabelle 2 nach Anfrage für Tabe

Beitrag lesen

Hallo,

Ist im Titel irgendwie die Monatsbezeichnung integriert?
Ja alle Titel fangen mit YYYY-MM-DD an, gefolgt von Text. Kann aber auch mal 200X sein oder so.

Nutze dafür lieber Datums- und Zeitfunktionen. Das ist cleverer.
Tue ich (wenn ich dich richtig verstanden habe). $thismonth und $lastmonth sind php date("Y-m") und das gleiche -1.

Du hast mich nicht verstanden. Speichere das Datum lieber in einer Spalte vom Datentyp DATE ab und selektiere nach dieser Datumsspalte.

Einfacher, das ist die Frage. Es geht mit MIN(), MAX() oder ähnlichem, mit einer korrelierten Unterabfrage, wie von mir bereits verlinkt.
Tja nur wie einbinden? t2.rc_title soll nur einmalig im ON ausgegeben werden und zwar von der Zeile mit min(t2.rc_id).

Und wo bist Du genau hängengeblieben? Für genau solche Aufgaben nutzt man korrelierte Unterabfragen. Ok, ich versuch's Dir Schritt-für-Schritt zu erklären (ohne Deine WHERE-Klausel, ORDER BY und LIMIT, die sich ja nicht ändern):

1. Wir schauen, was aus der Tabelle recentchanges benötigt wird, siehe Dein eigenes Statement:

» SELECT  

>   t1.page_namespace, t1.page_title, t1.page_is_redirect,  
>   t2.rc_title, t2.rc_timestamp, t2.rc_user, t2.rc_user_text  
> FROM page t1 LEFT JOIN recentchanges t2  
>   ON t1.page_title = t2.rc_title  

Du benötigst
  - rc_title
  - rc_timestamp
  - rc_user
  - rc_user_text,

das führt zunächst (mit Mehrfachnennungen) zu

SELECT  
    rc_title,      -- ich halte nichts von Tabellenpräfixen in Spaltennamen.  
    rc_timestamp,  
    rc_user,  
    rc_user_text  
FROM  
    recentchanges  

Nun möchtest Du bei gleichem Titel nur diejenigen, die den kleinsten id-Wert (rc_id) aufweisen, wir nutzen eine korrelierte Unterabfrage:

  
SELECT                           -- Gib mir  
    rc_title,                    -- die gewünschten Spalten  
    rc_timestamp,  
    rc_user,  
    rc_user_text,  
    rc_id                        -- (damit Du die Richtigkeit prüfen kannst)  
FROM                             -- aus meiner Tabelle, die wir mit einem  
    recentchanges rc1            -- Alias ansprechen, um sie von der  
                                 -- Verwendung im Subselect zu unterscheiden  
WHERE                            -- wobei nur die Datensätze gewünscht sind  
    rc1.rc_id = (                -- bei denen die id gleich  
        SELECT                   -- der  
            MIN(rc2.rc_id)       -- kleinsten id  
        FROM                     -- aus  
            recentchanges rc2    -- deiner Tabelle  
        WHERE                            -- wobei innere und äußere Abfrage  
            rc2.rc_title = rc1.rc_title  -- über gleichen Titelnamen in  
    )                            -- Beziehung zueinander stehen (korreliert sind)  

2. Im zweiten Schritt joinst Du einfach Deine Seiten-Tabelle mit dieser Abfrage. Join-Spalte ist die Titel-Spalte:

SELECT  
    p.page_namespace,  
    p.page_title,  
    p.page_is_redirect,  
    -- rc.rc_title       -- wird nicht benötigt  
    rc.rc_timestamp,  
    rc.user,  
    rc_user_text  
FROM  
    page p               -- p ist sinnvoller als ein aussageloses t1  
LEFT OUTER JOIN (        -- Join-Partner ist die korrelierte Unterabfrage  
    SELECT  
        rc_title,  
        rc_timestamp,  
        rc_user,  
        rc_user_text     -- (hier ohne die überflüssige id-Spalte)  
    FROM  
        recentchanges rc1  
    WHERE  
        rc1.rc_id = (  
            SELECT  
                MIN(rc2.rc_id)  
            FROM  
                recentchanges rc2  
            WHERE  
                rc2.rc_title = rc1.rc_title  
        )  
    ) rc                 -- die zwingend einen Aliasnamen benötigt,  
                         -- damit Du auf die Spalten zugreifen kannst.  

Anmerkungen:

- t1, t2 sind im Allgemeinen verbesserungswürdige Aliasnamen.
  - bei einem korrelierten Subselect dürfen die zwei Namen dagegen gerne
    mit einer Ziffer unterschieden werden.
  - Eine id sollte man nicht mit zusätzlicher Information ausstatten, nutze
    für den ältesten (oder neuesten) Eintrag Zeitinformationen, zum Beispiel
    eine DATETIME oder (MySQL-)TIMESTAMP-Spalte.
  - wie bereits angemerkt, halte ich Spaltenpräfixe aus dem Tabellennamen
    für keine besonders gute Idee.
  - Die Datumsinformation für Deine WHERE-Klausel bringe (zusätzlich zum
    Titel) in einer DATE-Spalte unter.

Freundliche Grüße

Vinzenz