J'essaie de créer une nouvelle table: _clients
qui sera simplement rempli pour le moment avec le user_id
colonne de #__user_usergroup_map
.
Idéalement, le code ci-dessous devrait extraire tous les id
de #__user_usergroup_map
table si correspondant group_id = 10
et uniquement les identifiants qui n'existent pas déjà dans le _clients
table.
Cela semble fonctionner lorsque j'ajoute/supprime des utilisateurs de la group_id = 10
dans phpmyadmin. Le $ncl
montre une liste correcte.
#__clients
mises à jour avec succès lors de l’actualisation de la page, mais j’obtiens une erreur SQL pour l’insertion de la clé primaire en double sur #__clients
. Il semble qu'il tente d'ajouter le même utilisateur à #__clients
à nouveau (l'utilisateur a été ajouté à la table lors de la première actualisation).
Je pensais que ce code ne devrait sélectionner que $ncl
car ces identifiants clients ne sont pas déjà dans le #__clients
table. Quelqu'un a des pensées?
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('a.user_id', 'a.group_id', 'b.id')
->from('#__user_usergroup_map as a', '#__clients as b');
$query->join('RIGHT', '#__clients AS b ON a.user_id != b.id')
->where('a.group_id = ' . $db->quote("10"));
$db->setQuery($query);
$ncl = $db->loadColumn();
print_r($ncl);
foreach($ncl as $encl) {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->insert('#__clients')
->set('id = ' . (int) $encl);
$db->setQuery($query);
$db->execute();
}
Vous pouvez ajuster votre code pour:
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('a.user_id as id') /* changed to load object and insert it */
->from('#__user_usergroup_map as a')
->leftJoin('#__clients AS b ON a.user_id = b.id') /* you should join with "=" not with "!=" */
->where('a.group_id = ' . $db->quote("10"))
->where('b.id IS NULL'); /* and filter to "new only" like this */
$ncl = $db->setQuery($query)->loadColumn();
print_r($ncl);
foreach($ncl as $encl) {
$db->insertObject('#__clients',$encl); /* less code this way */
}
cela fonctionnerait bien avec ce code, mais vous pouvez aller plus loin et le faire
$db = JFactory::getDBO();
$sel_query = $db->getQuery(true);
$ins_query = $db->getQuery(true);
$sel_query->select('a.user_id as id')
->from('#__user_usergroup_map as a')
->leftJoin('#__clients AS b ON a.user_id = b.id')
->where('a.group_id = ' . $db->quote("10"))
->where('b.id IS NULL');
$ins_query->insert('#__clients')
->columns('id')
->values($sel_query);
$db->setQuery(str_replace('VALUES','',$ins_query))->execute();
de cette façon, vous ferez le travail avec une seule demande.
Je viens tout juste de réaliser une méthode plus simple ... Comme j'avais déjà créé des tableaux existants, je pouvais simplement utiliser quelque chose comme:
$filteredFoo = array_diff($foo, $bar);
Ce qui filtrera les doublons des deux tableaux représentant chaque table, puis effectuera une insertion SQL avec le $ filtersFoo sans risque de doublons.
Parce que vous avez seulement besoin d'insérer des données de #__user_usergroup_map
À #__clients
Où id
est nul ET où group_id
Est 10
, Vous devez utiliser LEFT JOIN
Pour rejoindre les tables. D'autres jointures élimineront les lignes qui produisent une colonne NULL
et ce n'est pas souhaitable.
| #__user_usergroup_map | LEFT JOIN ON user_id=id | #__clients |
|------------------------| < |--------------|
| user_id | group_id | < | id |
|-----------|------------| < |--------------|
| 1 | 10 | < | NULL |
| 2 | 9 | < | NULL |
| 3 | 10 | < | NULL |
| 4 | 6 | < | NULL |
| 5 | 10 | < | 5 | //previously INSERTED for demonstration's sake
| 6 | 10 | < | NULL |
| 7 | 10 | < | NULL |
| 8 | 10 | < | NULL |
| 9 | 4 | < | NULL |
| 10 | 10 | < | NULL |
-------------------------- ----------------
Avant d’arriver aux solutions, je voudrais attirer l’attention sur le fait que votre syntaxe php/Joomla ne génère pas votre requête.
$query = $db->getQuery(true) ->select('a.user_id', 'a.group_id', 'b.id') ->from('#__user_usergroup_map as a', '#__clients as b') ->join('RIGHT', '#__clients AS b ON a.user_id != b.id') ->where('a.group_id = ' . $db->quote("10")); echo $query->dump();
Génère:
SELECT a.user_id // 2nd & 3rd columns are lost (should have been written as an array, but they were unimportant anyhow)
FROM prefx_user_usergroup_map as a // comma joined table is lost (not that it was good for anything)
RIGHT JOIN prefx_clients AS b ON a.user_id != b.id // this is not the correct join, nor ON logic
WHERE a.group_id = '10' // this is half of what is required
Cela retournera zéro lignes.
Bien que je sois confiant que l'extrait de code d'Alexandr fournira le résultat attendu, car la logique/syntaxe est bonne, je vais vous proposer ma version qui présente quelques différences.
$db = JFactory::getDBO();
try {
$select_query = $db->getQuery(true)
->select("A.user_id")
->from("#__user_usergroup_map A")
->leftJoin("#__clients B ON A.user_id = B.id")
->where("A.group_id = 10 AND B.id IS NULL");
//echo $select_query->dump();
$insert_query = $db->getQuery(true)
->insert('#__clients')
->columns('id')
->values($select_query);
// echo $insert_query->dump();
$db->setQuery($insert_query);
$db->execute();
// echo $db->getAffectedRows() , " row(s) inserted into clients table";
} catch (Exception $e) {
echo "Syntax Error"; // . " & Error: " . $e->getMessage();
}
J'ai testé mon extrait de code pour réussir sur mon hôte local. J'ai également créé un Démo SQLFiddle si quelqu'un veut jouer.
getQuery()
pour éliminer les mentions dupliquées de ${Word}_query
.qn()
ou q()
parce qu'ils ne sont pas nécessaires pour des raisons d'analyse/de sécurité.SELECT
parce que ce n'est pas obligatoire.setQuery(str_replace('VALUES','',$ins_query))
n'est pas nécessaire.Si quelqu'un craint que je vole sans vergogne la solution d'Alexandr, je publierai une construction de requête en force brute différente qui aura le même effet si votre colonne #__clients.id
Est un PRIMARY/UNIQUE KEY
. Je ne pense pas que j'utiliserais cette solution moins élégante (même si, pour une raison quelconque, elle était légèrement plus performante).
$select_query = $db->getQuery(true)
->select("A.user_id")
->from("#__user_usergroup_map A")
->where("A.group_id = 10");
// echo $select_query->dump();
$insert_query = $db->getQuery(true)
->insert('#__clients')
->columns('id')
->values($select_query);
$db->setQuery(str_replace("INSERT", "INSERT IGNORE", $insert_query));