holgi: Mysql, join, count(), where...

Hi,

  
SELECT track . * , COUNT( tm.track_id ) AS meta_count, pool_track . *  
FROM track, pool_track  
LEFT OUTER JOIN (  
  
SELECT track_id  
FROM track_meta  
) AS tm ON ( tm.track_id = track.track_id )  
WHERE track.make_user_id = 1  
AND track.track_id = pool_track.track_id  
AND pool_track.pool_id = 11  
ORDER BY track.artist ASC  
LIMIT 0 , 50  

Bekomme:

  
#1054 - Unknown column 'track.track_id' in 'on clause'  

Was ist daran falsch?

Ich gehe über drei Tabellen, wovon eine als Join mit Subselect der mir einfach nur einen Count() übergeben soll. In pool_track sind Assoziationen, in track sind die eigentlichen Datensätze um die es geht und in track_meta sind mehrere Eigenschaften als Datenpaar gespeichert (Name, Wert). Ich möchte A) die Anzahl der in track_meta gespeicherten Datensätze. Und B) die Datensätze, die in pool_track mit pool_id assoziiert sind.

Danke

  1. Hallo,

    SELECT
        track.,
        COUNT( tm.track_id ) AS meta_count,
        pool_track.

    FROM
        track,
        pool_track
    LEFT OUTER JOIN (
        SELECT track_id
            FROM track_meta
        ) AS tm
    ON
        tm.track_id = track.track_id
    WHERE
        track.make_user_id = 1
    AND
        track.track_id = pool_track.track_id
    AND
        pool_track.pool_id = 11
    ORDER BY
        track.artist ASC
    LIMIT 0, 50

      
    
    > Bekomme:  
      
    völlig erwartungsgemäß ([seit MySQL 5.0.12](http://dev.mysql.com/doc/refman/5.0/en/join.html))  
      
    
    > ~~~sql
      
    
    > #1054 - Unknown column 'track.track_id' in 'on clause'  
    > 
    
    

    Was ist daran falsch?

    der Versuch mit dem Einsatz des Kommaoperators ohne Klammerung und einer WHERE-Klausel einen impliziten INNER JOIN zu erzielen, statt einfach die explizite JOIN-Syntax zu verwenden.

    Ich gehe über drei Tabellen, wovon eine als Join mit Subselect der mir einfach nur einen Count() übergeben soll.

    warum ermittelst Du nicht im Subselect wirklich den gruppierten Wert? So hast Du ein typisch kaputtes Statement, das sowieso höchstens von MySQL akzeptiert wird. In allen DBMS (außer MySQL) musst Du - da Du eine Aggregatsfunktion einsetzt - nach allen Spalten gruppieren, die nicht aggregiert sind.

    Freundliche Grüße

    Vinzenz

    1. warum ermittelst Du nicht im Subselect wirklich den gruppierten Wert? So hast Du ein typisch kaputtes Statement, das sowieso höchstens von MySQL akzeptiert wird. In allen DBMS (außer MySQL) musst Du - da Du eine Aggregatsfunktion einsetzt - nach allen Spalten gruppieren, die nicht aggregiert sind.

      ja, so habe ich es gelöst. performance ist dank paginator. also hole ich nicht unendlich viele datensätze, sondern maximal 200. insofern ist das ok.

        
        
      SELECT track.* , ( SELECT COUNT(*) FROM track_meta AS tm WHERE tm.track_id = track.track_id) AS meta_count , ( SELECT COUNT(*) FROM pool_track AS pt WHERE pt.track_id = track.track_id) AS pool_count  
      FROM track  
      WHERE track.make_user_id = 1  
      GROUP BY track.title  
      ORDER BY track.title asc  
      LIMIT 0,50  
        
      
      

      nun stelle ich mir die frage, warum ich eine WHERE nicht mit pool_track oder track_meta machen kann... da sagt mir mysql, dass diese nicht existieren. die ausgabe enhält aber felder mit diesen namen und den richtigen werten...

      1. Hallo,

        nun stelle ich mir die frage, warum ich eine WHERE nicht mit pool_track oder track_meta machen kann... da sagt mir mysql, dass diese nicht existieren. die ausgabe enhält aber felder mit diesen namen und den richtigen werten...

        weil Du implizite Joins nutzt:
        Du schreibst die Tabellen kommagetrennt hintereinander ohne Klammern zu benutzen. Genauso steht es in der von mir verlinkten Doku.

        Nutztest Du explizite Joins, so entfiele der Einsatz des Kommaoperators mit der von Dir unerwarteten Priorisierung - und es käme keine Fehlermeldung.

        Ich persönlich nutze *immer* die explizite Joinsyntax. Ich finde das einfacher, weil ich mir so nicht zwei verschiedene Syntaxarten merken muss und die Join-Bedingungen sauber von den Einschränkungen in der WHERE-Klausel getrennt sind.

        Freundliche Grüße

        Vinzenz

  2. Hello,

    SELECT track . * , COUNT( tm.track_id ) AS meta_count, pool_track . *
    FROM track, pool_track
    LEFT OUTER JOIN (

    SELECT track_id
    FROM track_meta
    ) AS tm ON ( tm.track_id = track.track_id )
    WHERE track.make_user_id = 1
    AND track.track_id = pool_track.track_id
    AND pool_track.pool_id = 11
    ORDER BY track.artist ASC
    LIMIT 0 , 50

    Du vermischst explizite (LEFT JOIN) und implizite (,) JOIN-Syntax. Dort ist zwischen MySQL 4 und 5.x eine Umstellung vorgenommen worden welche Abschnitte in welcher Reihenfolge ausgeführt werden, in deinem Fall erhält der LEFT JOIN den Vorzug, "track" ist zum Zeitpunkt der Auswertung der ON-Klausel noch nicht mit im Boot.  
    Wenn du doch sowieso hinterher track.track\_id = pool\_track.track\_id vergleichst, nimm doch hierfür auch gleich einen passenden JOIN.  
      
    Ich bin mir übrigens noch nicht sicher, dass du hinterher dein gewünschtes Ergebnis bekommst (von wegen mehrere Zeilen dank der JOINs), aber ich bin sicher du meldest dich dann mit einer GROUP BY-Frage nochmal :-P  
    Wenn du den anwesenden DB-Spezialisten einen Gefallen tun willst, dann verlasse dich dabei NICHT auf MySQLs [GROUP BY hidden fields](http://dev.mysql.com/doc/refman/5.1/de/group-by-hidden-fields.html)-Feature.  
      
    MfG  
    Rouven  
    
    -- 
    \-------------------  
    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& ([SelfCode](http://selfspezial.atomic-eggs.com/scode/selfcode.php?encodieren))  
      
    Let Bygones Be Bygones  --  Robert Pitscottie: "Chronicles of Scotland"