2015-12-22 4 views
6

私は3つのテーブル:tco_articles,tco_module_eostextおよびtco_articles_modulesを持っています。私のtco_articlesには一意のidキーがあります。各記事ごとに1つ。私のtco_module_eostextには、各記事に属する一意のinstance_idがあります。 私のtco_articles_modulesにはすべてarticle_idが含まれていますが、他の表では9倍の数値が使用されています。MySQLでクエリを実行するときにテーブルを接続する

enter image description here

だから私はあなたがtco_module_eostextに照会すると、空返すことinstance_idarticle_idを持つことができます。

正しい記事の正しい本文​​を返すクエリを作成したいと思います。

は、これまでのところ私が持っている:あなたはarticle_idは同じではなくinstance_idあることがわかります

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 
     ) 

global $wpdb; 
$posts = array(); 

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

これは、のようなすべてのインスタンスとIDの配列を返します。あなたは

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

を置くときあなたは空のかも知れませんが、

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

のためにあなたは、いくつかの本文テキストを持つことができます。

これは私の問題です。私はそれらのすべてを通過し、空でないものを除き、それらに正しい記事を割り当てる必要があります。私はtco_module_eostextテーブルからbodyテキストを追加したいのですが今

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 
     ) 
    ... 

:私は記事

のようなものを返す
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]; 

} 

出力に管理されます。

私はこれを自動的に行うために、またはこの時点でこれを実行してから$postsアレイに追加するために使用できるクエリはありますか?

180000+個の投稿がある場合、foreachのクエリ方法はちょっと遅いです。

何か助けていただければ幸いです。

+0

だから、' tco_module_eostext'は、複数の 'body'テキストを持つことができます。複数ある場合、どちらを取得したいのですか?最新のもの(instance_id DESCによる)? –

+0

'tco_module_eostext'テーブルの各' instance_id'には 'body'テキストが添付されています(各idに一意です)。しかし、1つの 'article_id'に対して9つの' instance_id'を保持する 'tco_articles_modules'を通らない限り、このテキストがどの記事に属しているかを知る方法はありません。この9つのうちの1つだけが正しいものであり、残りは空です。 'article_id'は' tco_articles'テーブルの 'id'と同じです。 –

+0

したがって、 'instance_ids'の9つのうちの1つのために常に' tco_module_eostext'に1行しか存在しないことは確かです。 –

答えて

2

あなただけの1行が各article_idに対してtco_module_eostextに常にあることを確認している場合は、あなただけの各article_idごとに1行が表示されますされ、(内部結合)JOINを使用することができます。

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 ..... 

しかし、そのarticle_idのために他の二つのテーブルにエントリがない場合、これは、いくつかの記事の任意の行は表示されません。しかし、これを解決する方法はまだあります。 LEFT OUTER JOINを使用して、instace_idのいずれかの行にtco_module_eostextの行がある場合にのみ結合を行うことができます。これにより、他のテーブルにデータがない場合、少なくともtco_articlesテーブルから記事情報を取得することができます。あなたが関連する複数の `instance_id`を持つことができるよう

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

これまでのところ、これは私が見る限りのトリックでした。記事テーブルの主キーが 'id'なので、最初の部分で小さなエラーが1つありました:' JOIN tco_articles_modules m ON m.article_id = a.id'。しかし、本体のテキストが追加された配列が返されました。ありがとう!これは私をたくさん助けます! :) –

+0

あなたは歓迎です、私は私の答えにその部分を修正します。 –

+1

私はおそらくこれを少し変更して、残りのデータベースを組み込む必要がありますが、少なくとも今は始める方法を知っています:)そして、foreachは大いに役立ちません!ありがとうございました :) –

0

なぜ参加を伴うクエリを使用しないのですか?

をテストしていない!:

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 

はそれがOUTERを見て参加しましtco_articles_modules

から割り当てられarticle_id持つすべての記事を取得する必要があります - あなたはINNER JOINをしてこれを交換することがありより速いクエリ。また、クエリでフィルタリングするWHERE条件が必要です。 mysqlテーブルの正しいインデックス作成についても注意してください。各結合カラムにインデックスを付ける必要があります。これにより、はるかに高速な結果が得られます。

+0

それは、データの重複があるかもしれないことに注意してください! –

+0

私はこれを行って、何が出てくるのか見てみましょう:) –

+0

Yaehでもデータの重複があるかもしれません。 ON文またはGROUP BY文のglobalyのどちらかを使用してグループ化する必要がある場合。あなたのデータのダンプを提供することができれば、私はあなたのために働くクエリを得ることができます。 – exxecc

関連する問題