Sto tentando di creare una nuova tabella: _clients
che verrà semplicemente popolato con, per ora, con il user_id
colonna da #__user_usergroup_map
.
Idealmente, il codice seguente dovrebbe estrarre tutti i id
da #__user_usergroup_map
tabella se corrispondente group_id = 10
e solo ID che non sono già presenti all'interno di _clients
tavolo.
Questo sembra funzionare quando aggiungo/rimuovo utenti da group_id = 10
in phpmyadmin. Il $ncl
mostra un elenco corretto.
#__clients
si aggiorna correttamente all'aggiornamento della pagina, tuttavia viene visualizzato un errore sql per l'inserimento della chiave primaria duplicata in #__clients
. Sembra che stia tentando di aggiungere lo stesso utente a #__clients
di nuovo (ha aggiunto l'utente alla tabella al primo aggiornamento).
Pensavo che questo codice dovesse selezionare solo $ncl
poiché tali ID client non sono già presenti in #__clients
tavolo. Qualcuno ha qualche pensiero?
$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();
}
Puoi adattare il tuo codice a:
$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 */
}
funzionerebbe bene con questo codice, ma puoi andare oltre e farlo
$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();
in questo modo eseguirai il lavoro con una singola richiesta.
Ho appena realizzato un metodo più semplice ... Dato che avevo già creato array esistenti, potevo semplicemente usare qualcosa del tipo:
$filteredFoo = array_diff($foo, $bar);
Ciò filtrerà i duplicati dai due array che rappresentano ciascuna tabella e quindi eseguirà un inserimento SQL con $ filteredFoo senza il rischio di duplicati.
Poiché hai solo bisogno di INSERIRE i dati da #__user_usergroup_map
A #__clients
Dove id
è nullo E dove group_id
È 10
, Devi utilizzare LEFT JOIN
Per unirsi ai tavoli. Altri join elimineranno le righe che producono una colonna NULL
e ciò non è desiderabile.
| #__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 |
-------------------------- ----------------
Prima di arrivare alle soluzioni, voglio richiamare l'attenzione sul fatto che la tua sintassi php/Joomla non sta generando la query desiderata.
$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();
Genera:
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
Questo restituirà zero righe.
Mentre sono fiducioso che lo snippet di Alexandr fornirà il risultato atteso perché la logica/sintassi è valida, offrirò la mia versione che presenta alcune differenze.
$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();
}
Ho testato il mio frammento per avere successo sul mio host locale. Ho anche creato una SQLFiddle Demo se qualcuno vuole giocare.
getQuery()
per eliminare menzioni duplicate di ${Word}_query
.qn()
o q()
perché non sono necessarie per motivi di analisi/sicurezza.SELECT
perché non è richiesta.setQuery(str_replace('VALUES','',$ins_query))
non è necessario.Nel caso in cui qualcuno sia preoccupato di rubare senza vergogna la soluzione di Alexandr, pubblicherò una diversa query-build con forza bruta che avrà lo stesso effetto supponendo che la tua colonna #__clients.id
Sia un PRIMARY/UNIQUE KEY
. Non penso che userei questa soluzione meno elegante (anche se, per qualche ragione, fosse leggermente più 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));