2015-12-22 9 views
6

Ho 3 tabelle: tco_articles, tco_module_eostext e tco_articles_modules. Il mio tco_articles ha la chiave univoca id. Uno per ogni articolo. Il mio tco_module_eostext ha un instance_id unico che appartiene a ciascun articolo. Il mio tco_articles_modules contiene tutti gli article_id s, ma ha 9 volte più instance_id s che vengono utilizzati in altre tabelle.Collegamento di tabelle durante l'esecuzione di query in MySQL

enter image description here

così posso avere article_id con instance_id che quando si esegue una query nel tco_module_eostext tornerà vuota.

Vorrei fare una query che restituirà il testo del corpo corretto per l'articolo corretto.

Finora ho:

global $wpdb; 
$posts = array(); 

$ids = $wpdb->get_results('SELECT DISTINCT instance_id, article_id FROM tco_articles_modules', ARRAY_A); 

Questo restituisce array con tutte le istanze e gli ID come:

Array 
(
    [0] => Array 
     (
      [instance_id] => 928615 
      [article_id] => 129396 
     ) 

    [1] => Array 
     (
      [instance_id] => 928616 
      [article_id] => 129396 
     ) 

    [2] => Array 
     (
      [instance_id] => 928617 
      [article_id] => 129396 
     ) 

    [3] => Array 
     (
      [instance_id] => 928618 
      [article_id] => 129396 
     ) 

Si può vedere che le article_id s sono gli stessi, ma instance_id. Quando si mette

$wpdb->get_results('SELECT body FROM tco_module_eostext WHERE instance_id=928617 ', ARRAY_A); 

È possibile ottenere vuoto, ma per

$wpdb->get_results('SELECT body FROM tco_module_eostext WHERE instance_id=928618 ', ARRAY_A); 

Si potrebbe avere un po 'il corpo del testo.

Questo è il mio problema. Devo esaminarli tutti e filtrare quelli non vuoti e assegnare loro l'articolo corretto. Sono riuscito a uscita gli articoli

foreach ($ids as $key => $value) { 
    $instance_ID = $value['instance_id']; 
    $article_ID = $value['article_id']; 

    $article_out = $wpdb->get_results('SELECT * FROM tco_articles WHERE id='.$article_ID.' ', ARRAY_A); 
    $posts[$article_ID] = $article_out[0]; 

} 

che restituisce qualcosa di simile:

Array 
(
    [129396] => Array 
     (
      [id] => 129396 
      [headline] => Bla bla bla title 
      [intro] => This is cool article intro 
      [needs_review] => 0 
      [published] => 2014-12-16 09:17:00 
      [unpublished] => 
      [hidden] => 0 
      [no_single_page] => 0 
      [permalink] => link-perma-link-here 
      [internal_slug] => 
      [type_id] => 3 
      [thread_id] => 0 
      [news_id] => 0 
      [header_game_id] => 0 
      [puff_hh_id] => 0 
      [puff_title] => 
      [hdrcol_id] => 900 
      [review_queued] => 
      [lock_timeout] => 0 
      [created] => 2014-12-16 09:17:00 
      [updated] => 2015-01-16 13:51:30 
      [created_by] => 84142 
      [updated_by] => 84142 
     ) 
    ... 

Ora vorrei aggiungere il testo body dalla tabella tco_module_eostext.

Esiste una query che posso utilizzare per eseguire questa operazione automaticamente o per eseguire questa operazione alla volta e quindi aggiungere l'array $posts?

Il metodo di query di foreach è un po 'lento quando si hanno più di 180000 post.

Qualsiasi aiuto è apprezzato.

+0

Quindi, 'tco_module_eostext' può avere più testo' body' poichè è possibile avere più 'instance_id' related. Se c'è più, quale vuoi ottenere? L'ultimo (by instance_id DESC)? –

+0

Per ogni 'instance_id' nella tabella' tco_module_eostext' c'è un testo 'body' allegato (univoco per ogni id). Ma non ho un modo di scoprire a quale articolo questo testo appartiene, a meno che non vada attraverso 'tco_articles_modules', che contiene 9' instance_id's per 1 'article_id'. Solo uno da questo 9 è quello giusto, il resto è vuoto. 'article_id' è uguale a' id' nella tabella 'tco_articles'. –

+0

Quindi, sei sicuro che ci sarà sempre una sola riga in 'tco_module_eostext' per (uno di) ogni 9' instance_ids'? –

risposta

2

Se si è certi che ci sia sempre una sola riga in tco_module_eostext contro l'article_id, è possibile utilizzare JOIN (join interno), che mostrerà una sola riga per ogni article_id.

SELECT a.*, t.body 
FROM tco_articles a 
JOIN tco_articles_modules m ON m.article_id = a.id 
JOIN tco_module_eostext t ON m.instance_id = t.instance_id 
//WHERE ..... 

Ma, questo non mostrerà alcuna fila di alcuni articoli se non v'è alcuna voce in altre due tabelle per questo article_id. Ma c'è ancora un modo per risolvere questo. Possiamo usare LEFT OUTER JOIN e quindi assicurarci di effettuare il join solo se esiste una riga in tco_module_eostext per qualsiasi instace_id. Questo assicurerà di ottenere almeno le informazioni dell'articolo dalla tabella tco_articles quando non ci sono dati in altre tabelle.

SELECT a.*, t.body 
FROM tco_articles a 
LEFT OUTER JOIN tco_articles_modules m ON m.article_id = a.id AND EXISTS (SELECT NULL FROM tco_module_eostext WHERE instance_id = m.instance_id) 
LEFT OUTER JOIN tco_module_eostext t ON m.instance_id = t.instance_id 
//WHERE ..... 
+1

Questo ha fatto il trucco fino a quel momento. Hai avuto un piccolo errore nella prima parte: "UNISCITI a tco_articles_modules m ON m.article_id = a.id' perché la chiave primaria nella tabella degli articoli è semplicemente' id'. Ma ha restituito l'array con il testo del corpo aggiunto. Grazie! Questo mi aiuterà molto! :) –

+0

Prego, sistemerò quella parte nella mia risposta. –

+1

Probabilmente dovrò modificarlo un po ', per includere il resto del mio db ma almeno ora so come iniziare :) E no foreach aiuta molto! Grazie ancora :) –

0

Perché non utilizzare una query con join?

Non testato !:

SELECT 
    article.*, 
    text.body as bodytext 
FROM 
    tco_articles_modules AS modules LEFT OUTER JOIN 
    tco_module_eostext AS text ON 
     modules.instance_id = text.instance_id LEFT OUTER JOIN 
    tco_articles AS article ON 
     article.id = modules.article_id 

si dovrebbe ottenere tutti gli articoli con il assegnato article_id da tco_articles_modules

Avere uno sguardo a outer join - si consiglia di sostituire questo con un'INNER JOIN per query più veloci. Inoltre, vuoi una condizione WHERE per il filtraggio nella query. Guarda anche la giusta indicizzazione nella tabella mysql - ogni colonna di collegamento dovrebbe essere indicizzata - questo otterrà risultati molto più veloci.

+0

Notando che, ci può essere la duplicazione dei dati! –

+0

Darò questo e vedere cosa viene fuori :) –

+0

Yaeh ci potrebbe essere la duplicazione dei dati pure. Se è necessario raggrupparli tramite l'istruzione ON o globaly nella sezione GROUP BY. Se potessi fornire un dump dei tuoi dati, potrei ottenere una query di lavoro per te. – exxecc