2012-02-21 124 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