2011-04-19 8 views
4

私はカテゴリとcat_pagesと呼ばれる2つのテーブルがあります。一意の結果行を持つMYSQL JOIN

カテゴリテーブルには、ID、タイトル、タイムスタンプの列があります。例えば:私は、このような

    ことを、IDのcat_pagesテーブルでカテゴリテーブルに参加しようとしている

    CREATE TABLE cat_pages (
        cat_id INT UNSIGNED 
         REFERENCES categories (id) 
         ON DELETE CASCADE ON UPDATE CASCADE, 
        page_id INT UNSIGNED 
         REFERENCES pages (id) 
         ON DELETE CASCADE ON UPDATE CASCADE, 
        UNIQUE INDEX (cat_id, page_id), 
        INDEX (page_id, cat_id), 
    ) Engine=InnoDB; 
    

    CREATE TABLE categories (
        id INT UNSIGNED PRIMARY KEY, 
        title VARCHAR(32), 
        `timestamp` TIMESTAMP, 
        INDEX (title) 
    ) Engine=InnoDB; 
    

    cat_pagesは2列、CAT_IDとpage_idのを持っています

  1. category_pagesテーブルにidがあるカテゴリのみが取得され、
  2. 各カテゴリは結果セットに1回表示されます

クエリ:

SELECT * FROM categories as c 
    LEFT JOIN cat_pages as p ON c.id = p.cat_id 

はcat_pagesテーブル内の複数の一致があるようにカテゴリ(複数回繰り返した結果セットを生成します。 cat_pagesテーブルに一致するものがない場合、各カテゴリは一度しか表示されないようにするには何が必要ですか?

+0

あなたの質問からLEFTを落として、最初のポイント – Dalen

+0

のコードはキングです。テーブルを記述するための最良の方法は、テーブル作成ステートメントとサンプルデータのためのINSERTステートメントを与えることです。あなたが提供した 'SELECT'クエリは、あなたが望むものを記述するのに非常に役立ちました。 – outis

答えて

9

cat_pagesにないカテゴリを使用しない場合は、左結合を使用しないでください。内部結合を使用します。左の結合には、右の表に一致する行がない場合でも、左の表のすべての行が含まれます(欠落しているフィールドにNULL値が指定されています)。右結合も同様ですが、右の表のすべての行が含まれます。外部結合には、左右の表のすべての行が含まれ、一致する行が結合され、一致しない行がNULL値と結合されます。一方、内部結合は、一致する行のみを含みます。別の言い方をすれば、左右のジョインの共通部分はインナージョインです。その結合は外部結合です。ジェフアトウッドは、円の中のセットが左右のテーブルではなく、左右のテーブルの左右のジョインの結果であることに注意する必要がありますが、Venn diagrams describing joinsという素敵な記事を投稿しました。 SELECT * ...については

SELECT DISTINCT c.* 
    FROM categories AS c 
    INNER JOIN cat_pages AS cp ON c.id = cp.cat_id 

は、「What is the reason not to use select *?は」

は、個別の行を取得するための別のアプローチは、EXISTS句またはINを使用することです参照してください。

が別個の行を取得するには、 DISTINCT修飾子を使用することができます(ただし、 EXPLAINがあなたに確かにあなたに教えてくれるだけですが)結合はもっと可能です。適切なインデックスが設定されていることを確認してください。

+0

素晴らしい答え、DISTINCTはまさに私が探していたものです...なぜ私が内部結合をしていないのか分かりません。セレクト*のヘッドアップにも感謝します。 – tgriesser

-2

なぜ内部結合を使用しないのですか?

SELECT * FROM categories as c INNER JOIN cat_pages as p ON c.id = p.cat_id 

それとも

SELECT * FROM categories as c LEFT JOIN cat_pages as p ON c.id = p.cat_id WHERE p.cat_id IS NOT NULL 

左左テーブルと右テーブルの上の一致にすべてを選択しましょう。

関連する問題