2012-02-21 108 views
1

我使用笨,我獲取信息想從兩個表調用信息:從兩個MySQL表

產品: ID, 名, 價格, 描述, TYPEID

產品類型: t類別, TNAME

我試圖拉從產品的所有信息,並使用Product.typeID相匹配的產品類型表,只拉了回來TNAME。大多數情況下,Product_Type表中至少有3行將具有相同的typeID。例如:

產品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(); 

任何幫助將不勝感激。

編輯:

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

如果你得到你的產品重複3次,您的加盟對子句的不工作,你做了笛卡爾積而不是左加入。你能提供一些導致你的問題的例子數據嗎?我對列product_type.tCategory和product.typeID的內容特別感興趣。嘗試用「左」替換「左外」。 – Basti 2012-02-21 06:59:56

+0

我在print_r時添加了它的樣子。它說左外的原因是我正在試驗這些設置,看看它們中的任何一個是否會產生我想要的。 – Claremont 2012-02-21 07:17:01

+0

不包括相關欄目。您正在通過列product_type.tCategory和product.typeID執行連接。 「左」連接只是「左外」連接的簡稱。經過短時間的研究,我發現你用「左」來稱呼它,例如'$ this-> db-> join('comments','comments.id = blogs.id','left');'http://codeigniter.com/user_guide/database/active_record.html – Basti 2012-02-21 07:21:06

回答

0

爲了有一個產品排含有填充了第2個表中的行,你可以加入這兩個表,並通過發揮集團列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-clause中不在group by-clause或聚合的列。由於product.id是主鍵,因此我們只會爲每個product.id獲取一個product.name,因此我們不關心3個product.name(來自與3個類型的聯接)中的哪一個被選中。他們都是一樣的。我們甚至可以在select-clause中寫任何(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:使用MAX()

在我們不允許使用列name下面的查詢,因爲我們只由列id分組進一步的解釋。

SELECT 
    id, 
    name /* not allowed */ 

FROM 
    product 

GROUP BY id 

我們只能選擇group by條款中的列。我們也可以使用不在group by條款中的列,儘管聚合函數如maxgroup_concat

解決這個問題,我們可以列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 

,因爲我們將兩列分組。

第二個方法是使用聚合函數,像Max:

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

FROM 
    product 

GROUP BY id 

product表(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的值。但由於id決定name,這些值都是一樣的:

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

FROM 
    product 

LEFT JOIN 
    product_type ON product.tName = product_types.tCategory 

將導致

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

通過product.id分組之後的結果會像

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

其中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" 

這將導致

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

太棒了,非常感謝您的時間。我希望你不要介意,但另外一個問題,我不明白你爲什麼使用max()sql命令,如果你不介意你能不能解釋一點。 – Claremont 2012-02-21 09:10:18

+0

我添加了一些進一步的解釋unter:**編輯1:進一步解釋使用max()**希望它有幫助。 – Basti 2012-02-21 09:38:31