J'utilise les méthodes JDatabaseQuery de Joomla pour sélectionner des colonnes de deux tables jointes, mais je ne comprends rien à l'extrait de code suivant.
//Initialize variables.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
//Create the base select statement.
$query->select('a.id as id, a.greeting as greeting, a.published as published')
->from($db->quoteName('#__diolegend','a'));
//Join over the categories.
$query->select($db->quoteName('c.title' ,'category_title'))
->join('LEFT',$db->quoteName('#__categories','c') . ' ON c.id =a.catid');
Voir dans la 2ème select()
, il n'y a aucune mention de a.catid
?
Comment peut-il être possible de récupérer a.catid
? Nous ne l'avons pas sélectionné de nulle part.
Je pense que la méthode de requête de Joomla select()
vous a dérouté. C’est une bonne raison pour laquelle je n’aime pas faire plusieurs appels select()
- car seulement UN SELECT
La clause est réellement générée.
Si vous appelez echo $query->dump();
immédiatement après la construction de votre requête, vous verrez la chaîne de requête suivante (avec votre préfixe de base de données à la place de #_
):
SÉLECTIONNEZ a.id en tant qu'id, une salutation en tant que salutation, une.publiée telle que publiée, `c`.`title` AS` category_title`
DE `lmnop_diolegend` AS` a`
LEFT JOIN `lmnop_categories` AS` c` ON c.id = a.catid
Je veux dire, vous pouvez obtenir la même requête générée en appelant select()
sur chaque nom de colonne.
->select('a.id AS id')
->select('a.greeting AS greeting')
->select('a.published AS published')
->select('c.title AS category_title')
Bien entendu, il est parfaitement correct de joindre deux tables de base de données à l’aide de colonnes que vous n’avez pas l’intention de renvoyer dans le jeu de résultats.
En joignant les deux tables, vous avez la possibilité de nommer une ou toutes les colonnes des deux tables impliquées dans la requête. En fait, il est préférable de NE PAS inclure de colonnes à moins que vous ne les utilisiez dans votre script. Utiliser *
Est le moyen simple/bref de sélectionner toutes les colonnes d'une table interrogée, mais cela n'a pas de sens de demander à la base de données de renvoyer des données dont vous n'avez pas besoin.
Parfois, vous pouvez voir une erreur qui se plaint d'une colonne ne figurant pas dans la clause SELECT
lorsque vous utilisez GROUP BY
, Mais JOIN
s ne déposera pas cette réclamation.
Quelques remarques sur le code de bâtiment de votre requête:
$query
, Vous évitez de taper $query
Plusieurs fois de plus pour chaque nouvel appel de méthode.a.
Et c.
) Ne sont pas utilisés lors de l'accès aux éléments du jeu de résultats.)select()
une seule fois et lui donner une chaîne de colonnes unique de sorte que toutes les colonnes soient au même endroit dans le code.quoteName()
- cela ne signifie pas qu'il est dangereux de les conserver, mais simplement qu'ils sont inutiles.AS
n'est pas nécessaire dans l'extrait ci-dessous, mais je pense qu'il améliore la lisibilité.try{}catch{}
, Un vidage de la requête rendue et une vérification de l'absence de lignes renvoyées.Voici un extrait que j'ai testé pour réussir sur mon hôte local:
$db = JFactory::getDbo();
try {
$query = $db->getQuery(true)
->select('a.id, a.greeting, a.published, c.title AS category_title')
->from("#__diolegend AS a")
->leftJoin("#__categories AS c ON c.id = a.catid");
echo $query->dump();
$db->setQuery($query);
$resultset = $db->loadAssocList();
if (!$resultset) {
echo "No Rows In Resultset";
} else {
foreach ($resultset as $row) {
echo "<div>";
echo "<div>ID: {$row['id']}</div>";
echo "<div>Greeting: {$row['greeting']}</div>";
echo "<div>Published: {$row['published']}</div>";
echo "<div>Category Title: {$row['category_title']}</div>";
echo "</div>";
}
}
} catch (Exception $e) {
echo "Syntax Error " , $e->getMessage(); // never show `$e->getMessage()` on a public site (only use privately / before your site is live)
}
Cela produira:
SELECT a.id, a.greeting, a.published, c.title AS category_title
FROM lmnop_diolegend EN TANT QUE
LEFT JOIN lmnop_categories AS c ON c.id = a.catid
puis un résultat défini comme:
ID: 1
Greeting: Hello
Published: 1
Category Title: English
ID: 2
Greeting: Bonjour
Published: 1
Category Title: French
C’est simple, l’objet $ query utilisé pour sélectionner les données de la table #__deolegend puis, une fois encore sur le même objet $ query, un select () est appelé, ce qui les ajoutera aux champs à sélectionner, puis une jointure sur le #. Table __categories sur c.id et a.catid, ce qui signifie que le #__deolegend doit contenir un catid de colonne. Peu importe que vous deviez sélectionner la colonne pour appliquer la jointure. Aussi, je vous suggère d'imprimer l'objet $ query en utilisant:
echo $query;
Vous pouvez ainsi avoir une meilleure idée de la requête finale. Vérifiez également d’abord la structure des tables. Si vous pouvez partager vos découvertes à ce sujet ici, nous pourrons peut-être mieux vous aider. J'espère que cela t'aides
Je ne sais pas quelle est votre préoccupation réelle, ... mais maintenant, après avoir regardé un peu plus près de cette requête, je ne suis pas aussi certain de la nature de cette requête.
Je veux dire que...
La requête ci-dessus voulait être un SELECT
avec un JOIN
- mais la jointure se produit sur la même table: #__diolegend
et cela n'a vraiment aucun sens.
Est-ce une erreur de copier/coller/typo, ou d'où avez-vous obtenu cette requête?
Hypothétiquement, la deuxième table devrait être quelque chose comme #__diolegend_categories
ou juste #__categories
et dans ce cas, Query aurait tenté de récupérer les données id
, greeting
et published
de #__diolegend
table avec la catégorie associée title
à partir du #__categories
table -
Joined sur l'ID de la catégorie existant dans les deux tables, en tant que clé primaire dans le #__categories
table et en tant que clé étrangère dans le #__diolegend
.