为了有一个产品排含有填充了第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