Avatar billede htx98i17 Professor
15. april 2008 - 22:41 Der er 24 kommentarer og
1 løsning

Unknown column tp.kundeid in on clause

Jeg har fået opdateret mysql 4.1.22 til mysql 5.0.41

Derefter får jeg følgende fejl (eksempel):
Unknown column 'tp.kundeid' in 'on clause'

Den fejl får jeg alle steder hvor jeg har givet en tabel en label såsom:
tblkunder AS tk

i LEFT JOINs og SELECT * FROM tblkunder AS tk

Hvad skyldes det?
Avatar billede erikjacobsen Ekspert
15. april 2008 - 22:44 #1
Hvis du kalder den tk, og bruger den som tp, så er det vel en fejl. Men ellers må du give et konkret eksempel.
Avatar billede htx98i17 Professor
15. april 2008 - 22:52 #2
Det var blot et eksempel som tilfældgvis ikke passede sammen.
Jeg tænker at det er en skærpelse i versionen...?

Men her er et konkret eksempel:

SELECT
                                                UNIX_TIMESTAMP(tp.oprettet) AS oprettet,
                                                UNIX_TIMESTAMP(tp.redigeret) AS redigeret,
                                                tp.id AS projektid,
                                                tp.projektnavn,
                                                IF(tk.firma != '',tk.firma,CONCAT(tk.fornavn,' ',tk.efternavn)) AS kunden,
                                                CONCAT(tk.firma,' ',tk.fornavn,' ',tk.efternavn,'\n',tk.adresse,if(tk.adresse2 != '', CONCAT('\n',tk.adresse2,'\n'),'\n'),tk.zipcode,' ',tk.city) AS kundenavn,
                                                CONCAT(tpa.adresse,(if(tpa.adresse2 != '', CONCAT('\n',tpa.adresse2,'\n'),'\n')),tpa.zipcode,' ',tpa.city,'\n',tpa.telefon) AS projektadresse,
                                                IF(tpa.adresse != '',CONCAT(tpa.adresse,' ',tpa.adresse2),CONCAT(tk.adresse,' ',tk.adresse2)) AS projektadressevej
                                           
                                            FROM
                                                tblprojektrel AS tpr,
                                                tblprojekt AS tp,
                                                tblorders AS tol
                                               
                                           
                                            LEFT JOIN
                                                tblkunder AS tk ON
                                                    tk.id = tp.kundeid
                                           
                                            LEFT JOIN
                                                tblprojektadresser AS tpa ON
                                                    tpa.projektid = tp.id
                                           
                                            WHERE
                                                tp.id = tpr.projektid
                                                AND tpr.type = 1
                                                AND tpr.relid = tol.id
                                                AND ISNULL(tp.lukket)
                                               
                                               
                                               
                                            GROUP BY
                                                tpr.projektid
                                               
                                            ORDER BY
                                                tpr.projektid DESC
Avatar billede htx98i17 Professor
15. april 2008 - 23:03 #3
Min første tanke var at det var en skærpelse på den måde at labels for en tabel skulle omgives af specialtegn etc?
Avatar billede erikjacobsen Ekspert
15. april 2008 - 23:08 #4
Det er vist noget med at du ikke skal blande "komma-joins", og "(left|inner|...)-joins"
Avatar billede htx98i17 Professor
15. april 2008 - 23:08 #5
komma-joins ved jeg ikke lige hvad er?
Avatar billede htx98i17 Professor
15. april 2008 - 23:10 #6
altså flere tabeller i en forespørgsel? såsom "...FROM tblkunder AS tk, tblvarer AS tv..." ?

Det kan de da ikke mene...
Avatar billede erikjacobsen Ekspert
15. april 2008 - 23:14 #7
Hvorfor ikke? Det er bare at have noget i retning af (udfyld selv ...-erne)

    FROM
        tblprojektrel AS tpr
    JOIN tblprojekt AS tp ON ...
    JOIN tblorders AS tol ON ...
    LEFT JOIN ...
Avatar billede htx98i17 Professor
15. april 2008 - 23:21 #8
Så den første tabel i FROM skal være som normalt og resten skal JOINES

Men den der almindelig JOIN har jeg ikke brugt før. Skal jeg så flytte betingelserne fra WHERE ned til den JOIN eller hvordan fungerer det?
Avatar billede erikjacobsen Ekspert
15. april 2008 - 23:27 #9
Ja, de betingelser der "passer til" joinen, skal stå efter ON.

Det er ikke sådan at den første tabel er speciel - den joines jo med nummer 2.

Du mener heller ikke at 7 er syndeligt anderledes end de andre tal i:  7+9+13
Avatar billede htx98i17 Professor
15. april 2008 - 23:29 #10
hvis jeg trimmer eksemplet fra kommentar 22:52 ned til:

SELECT
                                                *
                                            FROM
                                                tblprojektrel AS tpr,
                                                tblprojekt AS tp
           
                                            LEFT JOIN
                                                tblkunder AS tk ON
                                                    tk.id = tp.kundeid

Så kommer der ingen fejl. Det burde der jo gøre. ik? for det er jo samme princip hvor LEFT JOINS og komma-joins er blandet sammen.
Avatar billede htx98i17 Professor
15. april 2008 - 23:46 #11
Tak for hjælpen indtil videre her i aften. Jeg tjekker for svar imorgen tidlig igen.
Avatar billede erikjacobsen Ekspert
16. april 2008 - 08:37 #12
Du bruger heller ikke tpr i nogen af dine left joins. Det der med ikke at blande "komma-joins" og joins angivet med nøgleordet JOIN er bare den nemme regel.

Men det virker vel hvis du skriver JOIN alle steder, ikke?
Avatar billede erikjacobsen Ekspert
16. april 2008 - 09:11 #13
Og den forholdsvis officielle forklaring finder du fx her http://bugs.mysql.com/bug.php?id=12943

"Please notice that from version 5.0.12 on there is a change in
the syntax of JOIN ... ON (currently being documented) that
makes the syntax SQL:2003 compliant. The essense of the
change is that the ON condition of a JOIN ... ON clause may
reference only tables that are in one of the operands of the
JOIN. "
Avatar billede htx98i17 Professor
16. april 2008 - 18:02 #14
Jeg fik nedgraderet til tidligere version igen, da for mange sites var berørt og ikke fungerede.

Men for lige at forstå det korrekt...
Eller rettere: På siden du linker til er der et eksempel:

Den illegale:
select * from t1 join (t2 join t3 on t1.a = t3.c);
is incorrect because the operands of the second join are
't2' and 't3', but not 't1', thus referring to 't1.a' is an error.

Den legale:
select * from (t1 join t2) join t3 on t1.a = t3.c;
Here the first operand of the second join is a virtual table
  t1t2 = (t1 join t2), such that 't1t2' contains the column t1.a.

Jeg forstår ikke hvordan 3 tabeller kan joines uden at der er defineret en relation. Eksempelvis hvordan er t2 joined med t1 når ingen relation er defineret

Og hvorfor lavede de egentlig den ændring fra 4.1.22 til 5.0.41 ? hvad er årsagen, fungerede det ikke fint nok? mit gjorde da :)
Avatar billede erikjacobsen Ekspert
16. april 2008 - 18:21 #15
Der er to ting på det link: At de nu vil følge en standard - det er hvad du oplever. Og så at der søreme også er en fejl. Det sidste berører ikke dig.

Jeg synes det er fint at ændre systemer til at følge standarder, også selv om det ødelægger tidligere kode. Den kunne jo bare have fulgt standarden.
Avatar billede htx98i17 Professor
16. april 2008 - 18:26 #16
hehe jeg ved det godt :)

tak for deltagelsen. Jeg går ud fra du stadig ikke samler på point...
Avatar billede erikjacobsen Ekspert
16. april 2008 - 19:04 #17
Nej tak.
Avatar billede htx98i17 Professor
17. april 2008 - 12:08 #18
Jeg har prøvet at omskrive sql'en som du foreslog:

Gammel sql:
SELECT
    UNIX_TIMESTAMP(tp.oprettet) AS oprettet,
    UNIX_TIMESTAMP(tp.redigeret) AS redigeret,
    tp.id AS projektid,
    tp.projektnavn,
    IF(tk.firma != '',tk.firma,CONCAT(tk.fornavn,' ',tk.efternavn)) AS kunden,
    CONCAT(tk.firma,' ',tk.fornavn,' ',tk.efternavn,'\n',tk.adresse,if(tk.adresse2 != '', CONCAT('\n',tk.adresse2,'\n'),'\n'),tk.zipcode,' ',tk.city) AS kundenavn,
    CONCAT(tpa.adresse,(if(tpa.adresse2 != '', CONCAT('\n',tpa.adresse2,'\n'),'\n')),tpa.zipcode,' ',tpa.city,'\n',tpa.telefon) AS projektadresse,
    IF(tpa.adresse != '',CONCAT(tpa.adresse,' ',tpa.adresse2),CONCAT(tk.adresse,' ',tk.adresse2)) AS projektadressevej

FROM
    tblprojektrel tpr,
    tblprojekt tp,
    tblorders tol
   

LEFT JOIN
    tblkunder AS tk ON
        tk.id = tp.kundeid

LEFT JOIN
    tblprojektadresser AS tpa ON
        tpa.projektid = tp.id

WHERE
    tp.id = tpr.projektid
    AND tpr.type = 1
    AND tpr.relid = tol.id
    AND ISNULL(tp.lukket)
    AND tol.lukket LIKE '0000-00-00 00:00:00'
   
   
GROUP BY
    tpr.projektid
   
ORDER BY
    tpr.projektid DESC

------------------------

Omskrevet sql:

SELECT
    UNIX_TIMESTAMP(tp.oprettet) AS oprettet,
    UNIX_TIMESTAMP(tp.redigeret) AS redigeret,
    tp.id AS projektid,
    tp.projektnavn,
    IF(tk.firma != '',tk.firma,CONCAT(tk.fornavn,' ',tk.efternavn)) AS kunden,
    CONCAT(tk.firma,' ',tk.fornavn,' ',tk.efternavn,'\n',tk.adresse,if(tk.adresse2 != '', CONCAT('\n',tk.adresse2,'\n'),'\n'),tk.zipcode,' ',tk.city) AS kundenavn,
    CONCAT(tpa.adresse,(if(tpa.adresse2 != '', CONCAT('\n',tpa.adresse2,'\n'),'\n')),tpa.zipcode,' ',tpa.city,'\n',tpa.telefon) AS projektadresse,
    IF(tpa.adresse != '',CONCAT(tpa.adresse,' ',tpa.adresse2),CONCAT(tk.adresse,' ',tk.adresse2)) AS projektadressevej

FROM
    tblorders AS tol
   

JOIN
    tblprojekt AS tp ON
        tp.id = tpr.projektid
        AND ISNULL(tp.lukket)
       
JOIN
    tblprojektrel AS tpr ON
        tpr.relid = tol.id
        AND tpr.type = 1
       
JOIN
    tblkunder AS tk ON
        tk.id = tp.kundeid

LEFT JOIN
    tblprojektadresser AS tpa ON
        tpa.projektid = tp.id

WHERE
    tol.lukket LIKE '0000-00-00 00:00:00'
   
   
GROUP BY
    tpr.projektid
   
ORDER BY
    tpr.projektid DESC
-------------------------


De begge giver 59 poster, så resultatet ser ud til at være det samme.
Kan du se om omskrivningen ser ud til at skulle give samme resultat eller er der noget som vil kunne lave afvigelser?

Jeg har taget tid på hvor lang tid det tager at afvikle phpsiden, dvs kaldet til db og udskrift (mysql_fetch_array) til browseren. Det tager i begge tilfælde altid 0.08 - 0.14
Avatar billede erikjacobsen Ekspert
17. april 2008 - 13:16 #19
Jeg ville flytte
  AND ISNULL(tp.lukket)
  AND tpr.type = 1
ud til din where, da de ikke er join-betingelser. Det bør ikke give nogen forskel på nogen måde, men er for læselighedens skyld.

Ellers ser det helt korrekt ud. Og det er både betryggende og forventet, at det kører lige hurtigt på den ene og på den anden måde.
Avatar billede htx98i17 Professor
17. april 2008 - 16:39 #20
AND ISNULL(tp.lukket)
AND tpr.type = 1

Hvofor er det ikke join betingelser? har man kun primærnøgle og fremmednøgle i en JOIN (relationen) ?
Avatar billede erikjacobsen Ekspert
17. april 2008 - 16:47 #21
Man bør, i min verden, kun angive de betingelser, der binder tabeller sammen efter ON. Men det er funktionelt det samme.
Avatar billede htx98i17 Professor
17. april 2008 - 17:04 #22
okay

er det rigtig forstået at JOIN skal opfyldes, altså primær nøgle skal hænge sammen med fremmednøgle?

hvor LEFT join ikke behøves at finde en partner
Avatar billede erikjacobsen Ekspert
17. april 2008 - 19:07 #23
Jo, det er ofte sådan man skruer en join sammen. Det behøver dog ikke være formelt defineret som en fremmesnøgle i SQL-en. Joins kan være dyre, derfor få mysql til at fortælle dig hvordan den vil lave den (Explain kommandoen), og se om du har de rigtige indexer på.  ... i hvert fald hvis det tager for lang tid.

En left join behøver ikke matche noget i den "højre" tabel, men du får i så fald felter med NULL.
Avatar billede htx98i17 Professor
17. april 2008 - 19:23 #24
dvs jeg skal køre sql'en i eksempelvis phpmyadmin og klikke explain.
Og så vil jeg kunne se hvis den foreslår en anden måde at indexere på?
Avatar billede erikjacobsen Ekspert
17. april 2008 - 20:14 #25
Det er princippet ja, men man skal vide hvordan man læser sådan et Explain output. Og man skal helst gøre det på tabeller af forventet størrelse og indhold.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester