2012-02-21 37 views
1

私はCodeIgniterのを使用していますが、私は2つのテーブルからの情報を呼び出すようにしようとしています:取得情報

製品: ID、 名、 価格、 説明、 は

PRODUCT_TYPEをTYPEID: tCategory、 tName

Productからすべての情報を取り出し、Product.typeIDを使用してProduct_Typeテーブルに一致させ、tNameのみを取り戻そうとしています。ほとんどの場合、同じtypeIDを持つProduct_Typeテーブルから少なくとも3つの行があります。例:

商品1は20ドルで赤いシャツになり、タイプIでは大、中、小が必要になります。私はこれをやってしようとしてい

を登録しようが、それは私が必要とするだけでなく、シャツの情報を3回重複して3種類を提供します。すべてのヘルプをいただければ幸いです

$this->db->select('product.id, product.name, product.price, product.description, product_type.tName'); 
$this->db->from('product'); 
$this->db->where('perm_name', $id); 
$this->db->join('product_type', 'product_type.tCategory = product.typeId', 'LEFT OUTER'); 
$query = $this->db->get(); 

は、ここに私のコードです。

EDIT:

Array 
(
    stdClass Object 
     (
      [id] => 2 
      [name] => Tshirt 1 
      [price] => 20 
      [description] => Awesome tshirt 
      [tName] => 1 
    ) 

) 

Array 
(
    [0] => stdClass Object 
     (
      [tCategory] => 1 
      [tName] => Small 
    ) 

    [1] => stdClass Object 
     (
      [tCategory] => 1 
      [tName] => Medium 
    ) 
    [2] => stdClass Object 
     (
      [tCategory] => 1 
      [tName] => Large 
    ) 

) 
+0

になりますし、あなたがデカルト積の代わりに、左をしました参加する。あなたの問題につながるいくつかのサンプルデータを提供できますか?私は特にproduct_type.tCategoryとproduct.typeIDの列の内容に興味があります。 「LEFT OUTER」を単に「LEFT」に置き換えてみてください。 – Basti

+0

私はそれがprint_rのときに見えるものを追加しました。それは私が望むものを生み出すかどうかを確かめるために、私はそれらの設定を実験していたのです。 – Claremont

+0

関連する列は含まれません。 product_type.tCategory列とproduct.typeID列に対する結合を実行しています。 "left" joinは "left outer" joinの略です。短い研究の後、私はあなたがそれを単に "左"と呼んでいることに気づきました。 '$ this-> db-> join( 'comments'、 'comments.id = blogs.id'、 'left');' http://codeigniter.com/user_guide/database/active_record.html – Basti

答えて

0

製品の行を持っている第二表の行が移入されたコラムtypesが含まれている、あなたは、両方のテーブルを結合し、グループで遊ぶことができますいずれかの方法で:

SELECT 
    product.id, 
    max(product.name) as name, 
    max(product.price) as price, 
    max(product.description) as description, 
    group_concat(product_types.tName) as types 

FROM 
    product 

LEFT JOIN 
    product_type ON product.tName = product_types.tCategory 

GROUP BY product.id 

max(product.name)の後ろには魔法はありません。グループ句に含まれていない、または集約されているselect句の列を使用することはできません。 product.idは主キーであるため、product.idごとに1つのproduct.nameしか取得しないため、3つのproduct.name(3つのタイプの結合から)のどれが選択されるかは気にしません。彼らはすべて同じです。 select節にany(product.name)を書くこともできますが、mysqlがこれをサポートしているとは思いません。 =)

または相関サブクエリを行う〜

SELECT 
    product.id, 
    product.name, 
    product.price, 
    product.description, 
    (SELECT 
     group_concat(product_types.tName) 
    FROM product_types 
    WHERE product.tName = product_types.tCategory 
    GROUP BY product_types.tCategory 
    ) as types 

FROM 
    product 

私はそれを最適化するために、MySQLのが容易になるように最初のクエリを使用することをお勧めします。レコードのために:私はそれらのクエリをテストしていないので、彼らはいくつかの調整が必要な可能性があります。私に知らせて。

EDIT1:我々は唯一の列idによってグループ化されているため、MAX()私たちは列nameを使用することを許可されていない次の照会で

を使用するためのさらなる説明。

SELECT 
    id, 
    name /* not allowed */ 

FROM 
    product 

GROUP BY id 

ここでは、group byにある列のみを選択できます。我々はまたmaxgroup_concatのような集計関数はありますが、group by節にはない列を使用することがあります。私達はちょうど例えば、私たちは今nameに異なる値を持っている場合、我々は結果に複数のタプルを取得しますgroup by

-clause
SELECT 
    id, 
    name /* ok because it's in group by */ 

FROM 
    product 

GROUP BY id, name 

に列nameを追加することができますこの問題を解決するための

productテーブル(ID、名前)について

= {(1、アリス)、(1、ボブ)}我々は結果を得る

1, Alice 
1, Bob 

両方の列をグループ化したためです。第2のアプローチは、最大のような集約関数、使用している

productテーブル(ID、名前)について

SELECT 
    id, 
    max(name) /* ok because it's aggregated */ 

FROM 
    product 

GROUP BY id 

= {(1、アリス)、(1、ボブ)}我々は結果を得ますあなたの例では

1, Bob /* max(Alice,Bob) = Bob, because A < B */ 

私は、列product.idが主キーので、ユニークであると仮定。これは、id列の等しい値に対して異なる値をname列に持つことができないことを意味します。 {(1, Alice), (1, Bob)}はできませんが、おそらく{(1, Alice), (2, Bob)}です。現在GROUP BY product.idの場合、グループ内の各タプルに対してproduct.nameの値が得られます。 idnameを決めるので、しかし、これらの値は、すべて同じ:

SELECT 
    product.id, 
    product.name, 
    product_type.tName, 

FROM 
    product 

LEFT JOIN 
    product_type ON product.tName = product_types.tCategory 

は結果が

(1, F("White T-Shirt", "White T-Shirt", "White T-Shirt"), 
    G(Small, Medium, Large)), 
(2, F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt"), 
    G(Small, Medium, Large)) 
のようになりますproduct.idことによってそれをグループ化した後

(1, "White T-Shirt", Small), 
(1, "White T-Shirt", Medium), 
(1, "White T-Shirt", Large), 
(2, "Black T-Shirt", Small), 
(2, "Black T-Shirt", Medium), 
(2, "Black T-Shirt", Large) 

になります

ここで、FGは、selectで使用されている集約関数です。 Fについては、どの値を使用するかは関係ありませんが、すべて同じです。私たちはちょうどmaxを使用しました。 gではすべての値を連結するためにgroup_concatを使用しました。

ので

F("White T-Shirt", "White T-Shirt", "White T-Shirt") = "White T-Shirt" 
F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt") = "Black T-Shirt" 
G(Small, Medium, Large) = "Small, Medium, Large" 

これはあなたの製品が3回複製ゲットするならば、上の節あなたの参加者は動作しません

(1, "White T-Shirt", "Small, Medium, Large"), 
(2, "Black T-Shirt", "Small, Medium, Large") 
+0

素晴らしいです、ありがとうございました。私は心配していないが、他の1つの質問をしたい、私はなぜあなたが少しをさらに説明することができない場合は、max()sqlコマンドを使用して理解していない。 – Claremont

+0

私はいくつかのさらなる説明を追加しました:** Edit1:max()**を使用するためのさらなる説明は役に立ちました。 – Basti