爲了有一個產品排含有填充了第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
條款中的列,儘管聚合函數如max
和group_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))
其中F
和G
是在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")
如果你得到你的產品重複3次,您的加盟對子句的不工作,你做了笛卡爾積而不是左加入。你能提供一些導致你的問題的例子數據嗎?我對列product_type.tCategory和product.typeID的內容特別感興趣。嘗試用「左」替換「左外」。 – Basti 2012-02-21 06:59:56
我在print_r時添加了它的樣子。它說左外的原因是我正在試驗這些設置,看看它們中的任何一個是否會產生我想要的。 – Claremont 2012-02-21 07:17:01
不包括相關欄目。您正在通過列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