Quelle est la syntaxe de JDatabase pour une instruction JOIN qui joint deux tables sur une variable égale à x ou nulle? Par exemple, il rejoint plusieurs valeurs.
J'ai trouvé quelques exemples qui me montrent que vous pouvez faire cela dans SQL normal mais je ne sais pas comment cela se traduit par la syntaxe JDatabase.
Ma requête fonctionne actuellement lorsque la variable (a.animal) est égale à b.id, mais j'ai besoin qu'elle soit également associée lorsque la variable (a.animal) est vide.
$query1 = $db->getQuery(true)
->select ($db->quoteName(array('a.date','a.reminder','a.type','a.animal','a.mob')))
->select ($db->quoteName('b.nameandid') .'AS'. $db->quote('animalname'))
->from ($db->quoteName('app_reminders', 'a'))
->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').')')
->where ($db->quoteName('a.date') . '>=' . 'NOW()', 'AND')
->where ($db->quoteName('a.user_id') . 'LIKE' . $db->quote($userid));
Dans votre instruction ON
, vous devriez pouvoir ajouter plusieurs conditions combinées par AND
et OR
. Donc, quelque chose comme ceci devrait faire l'affaire:
->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').' OR ' . $db->quoteName('a.animal') . ' IS NULL)')
J'ai quelques préoccupations et améliorations à apporter, mais je vais tout d'abord passer directement au code et expliquer ensuite.
Vous voulez générer une requête qui se présente comme ceci:
SELECT a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'
FROM app_reminders a
LEFT JOIN app_animal b ON a.animal = b.id
WHERE a.date >= NOW() AND a.user_id = 3
Notez que mon JOIN
et le JOIN
de la question de votre page StackOverflow liée utilisent LEFT JOIN
. Le PO sur cette question ne veut que des lignes avec des valeurs dans toutes les tables jointes. La réponse utilise JOIN
(jointure régulière aka INNER JOIN
). Cela ignore les lignes contenant null
pour la valeur de la jointure.
Vous voulez quelque chose de différent. Vous souhaitez que les lignes de la première table, que la seconde contienne ou non une valeur qualificative à joindre sur la ligne. Pour cela, vous voulez LEFT JOIN
. Voici une démonstration de SQLFiddle si vous voulez jouer et comparer les résultats des jointures. (Si ce n'est pas l'action que vous recherchez, vous devriez pouvoir utiliser ce lien pour exprimer ce qui ne va pas.) Avec LEFT JOIN
, Vous n'avez pas besoin d'ajouter la condition supplémentaire pour vérifier IS NULL
.
En plus ...
LIKE
mais sans les caractères génériques %
Ou _
, Il n'y a donc aucune raison d'écrire LIKE
. Simplifiez simplement jusqu'à =
.date
et type
sont mysql [~ # ~] mots-clés [~ # ~] , ils ne le sont pas MOTS-CLÉS RÉSERVÉS afin qu'ils ne soient pas obligés d'être emballés dans des backticks. Ceci est également vrai pour toutes vos autres colonnes et les noms de tables. Vous êtes invités à utiliser qn()
/quoteName()
sur toutes ces entités, mais cela ne fera qu'ajouter une surcharge à la syntaxe et au code de votre requête.'LIKE'
est meilleur que ' LIKE '
)$userid
Sous la forme d'un entier (int)
Lorsque vous l'appliquez à votre requête. Il n'est pas nécessaire de citer les valeurs entières.select()
et un where()
. (Lors de la jonction de plusieurs tables, la présence de plusieurs appels join()
est logique/intuitive.)Syntaxe Joomla (aucune méthode de citation appelée):
$query = $db->getQuery(true)
->select("a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'")
->from("app_reminders a")
->joinLeft("app_animal b ON a.animal = b.id")
->where("a.date >= NOW() AND a.user_id = " . (int)$userid);
p.s. Si vous voulez réellement utiliser LIKE
avec un ou plusieurs caractères génériques, , cet article vous montrera le moyen sécurisé - provenant de la Documentation Joomla.