web-dev-qa-db-fra.com

Colonne MySQL inconnue dans la clause ON

J'ai la requête MySQL suivante:

SELECT p.*,
    IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
    pm.MediaID,
    date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
    astext(pg.Geometry) AS Geometry
FROM property p, propertygeometry pg
    JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
    LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
    LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
    AND p.PropertyGeometryID = pg.id
GROUP BY p.id

Et je reçois cette erreur:

# 1054 - Colonne inconnue 'p.id' dans 'on clause'

Pour autant que je puisse voir, la requête semble correcte, une idée de ce qui pourrait être faux?

54

Ne mélangez pas les jointures de style ANSI-89 et ANSI-92. Ils ont une priorité différente qui peut conduire à des erreurs confuses, et c'est ce qui s'est produit ici. Votre requête est interprétée comme suit:

FROM property p, (
    propertygeometry pg
    JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
    ...
)

Dans ce qui précède, les jointures utilisant le mot clé JOIN sont évaluées en premier avant que la jointure de type virgule soit même prise en compte. À ce stade, la table p n'est pas encore déclarée.

Depuis le manuel MySQL :

Cependant, la priorité de l'opérateur virgule est inférieure à INNER JOIN, CROSS JOIN, LEFT JOIN, etc. Si vous mélangez des jointures par virgule avec les autres types de jointures lorsqu'il existe une condition de jointure, une erreur de la forme Colonne inconnue 'nom_colonne' dans 'clause on' peut se produire. Des informations sur la résolution de ce problème sont fournies plus loin dans cette section.

Je recommanderais toujours en utilisant des jointures de style ANSI-92, c'est-à-dire en utilisant le mot clé JOIN:

SELECT p.*,
    IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
    pm.MediaID,
    date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
    astext(pg.Geometry) AS Geometry
FROM property p
    JOIN propertygeometry pg ON p.PropertyGeometryID = pg.id
    JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
    LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
    LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
GROUP BY p.id

En relation:

95
Mark Byers

Comme indiqué précédemment, il y a un problème de priorité lors de l'utilisation de jointures via l'opérateur virgule où LEFT JOIN sera exécuté et les références aux alias de table n'existeront pas à ce moment-là. Bien que vous puissiez implicitement dire à MySQL d'utiliser un JOIN via cette instruction, vous pouvez également dire à MySQL d'évaluer d'abord les tables jointes par des virgules, puis d'exécuter ainsi la jointure gauche:

SELECT p.*,
IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
pm.MediaID,
date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
astext(pg.Geometry) AS Geometry
FROM (property p, propertygeometry pg)
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
AND p.PropertyGeometryID = pg.id
GROUP BY p.id

Notez que les tables séparées par des virgules sont contenues entre parenthèses (). Les alias et colonnes de table seront désormais disponibles pour vos autres JOIN.

10
Tom Mulkins

Je suis tombé sur cette colonne d'erreur inconnue, le différentiel est que la requête est construite via HQL à l'intérieur de session.executeQuery ("sélectionnez id, nom, somme (payé), custType du groupe cust par marque") c'est pourquoi avoir à taper manuellement la jointure interne ou join mot-clé n'est pas une option car le hql est celui qui le génère. il produit une requête qui ressemble à ceci:

select cust_id, name, sum(paid), c.custTypeId
from customer c, custType ct
on c.custTypeId  = ct.custTypeId 

il indique la colonne "unknown c.custTypeId" lorsque je suis sûr à 101% qu'il porte cette colonne.

Mes cours/relations:

Customer {
Integer custId
CustomerType custType
}

CustomerType{
 Integer custTypeId
string code
}

le problème réside dans la virgule dans la ligne "from customer, custType". cela devrait être avec le mot JOIN comme réponse indiquée ci-dessus. mais comme c'est HQL et qu'il est généré, je ne peux pas faire ça. Ce que j'ai fait est modifié par requête et au lieu de taper select custType, j'ai tapé select custType.id, custType.code

Je sais que c'est basique mais pour les débutants comme moi, c'était un combat.

1
user742102