2010-12-01 120 views
2

我正在处理一个包含子查询的轻微复杂(至少对我来说)的mySQL查询,它不会很好地说实话。mySQL:子查询到数组?

SELECT `products`.`id`, `product`.`price`, 
    (SELECT `value` FROM (`productValues`) 
    WHERE `productValues`.`product` = 'product.id' 
) as values 
FROM (`products`) WHERE`product`.`active` = 1 

目前的结果是这样的:

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [active] => 1 
      [price] => 1000 
      [values] => 
     ) 
) 

我要的是价值元素也成为在值表,匹配(WHERE productValues.product = product.id)的所有元素的数组。

我在做什么错?

回答

3
SELECT p.id, p.price, pv.`value` 
FROM products p 
    JOIN productValues pv 
    ON p.product_id=pv.product 
WHERE p.active = 1 
ORDER BY p.id; 

给出了一个表,每一行对应一个pv.value(顺便说一句,使用像“价值”的保留字是不推荐)。通过p.id排序输出可确保特定产品的所有行都在一起。因此,在应用程序层中,循环遍历行,每当p.id发生变化时都会更改产品。

$old_id=NULL; 
$datastructure=array(); 
while($arr=$result->fetch_assoc()){ 
    if($arr['id']!=$old_id){ 
    $datastructure[$arr['id']][price]=$arr['price']; 
    $old_id=$arr['id']; 
    } 
    $datastructure[$arr['id']]['values'][]=$arr['value']; 
} 

我给出的结构也许不是你要的,因为它可以让你通过数组键访问特定产品的一个更灵活。

5

我不确定是否可以像这样返回子查询。一种解决方案是在你的子查询中使用GROUP_CONCAT来将所有值集中到一个字符串。然后,在结果中,可以使用explode将此字符串拆分为数组。

更新:子查询只能匹配1排
来源:http://dev.mysql.com/doc/refman/5.0/en/subquery-errors.html

+0

这是一个合理的解决方案,只有当`GROUP_CONCAT`保证产生一个长度<= 255个字符的字符串。否则,该值将被截断。 – dnagirl 2010-12-01 14:44:03

0

我觉得“值”属性将永远是一个变量。不管PHP如何,都认为纯粹的SQL - 如果你在sql编辑器中运行这样的查询 - 你会将values属性看作一列。如果您要求检索多个专栏,您会得到一个错误。
通常,SQL查询总是平坦的 - 一个级别。
我的建议 - 运行2个查询,并将它们放在PHP层中。

1

MySQL只能返回一个二维结果集,它不能返回更复杂的数据结构。你将不得不做两个分离的查询,并在你的应用程序中加入结果。

例在PHP中:

<?php 

//getting a list of products 
$result = mysql_query("SELECT `products`.`id`, `product`.`price` 
         FROM (`products`) 
         WHERE`product`.`active` = 1"); 

$product_ids = array(); 
$products = array(); 
while($r = mysql_fetch_assoc($result)) 
{ 
    $products[$r['id']] = $r; 
    $product_ids[] = $r['id']; 
} 

$comma_separated_ids = implode(",", $product_ids); 

//getting a list of all product values for given products 
$result = mysql_query("SELECT `value`, `product` 
         FROM (`productValues`) 
         WHERE `productValues`.`product` IN ('$comma_separated_ids')"); 

//joining them together 
while($r = mysql_fetch_assoc($result)) 
{ 
    if (!isset($products[$r['product']]['values'])) 
     $products[$r['product']]['values']; 

    $products[$r['product']]['values'][] = $r['value']; 
} 

?> 

基于GolezTrol的回答有点更优雅的变体:

<?php 
$result = mysql_query("SELECT `products`.`id`, GROUP_CONCAT(`productValues`.`value`) AS `values` 
         FROM `products`, `productValues` 
         WHERE`product`.`active` = 1 AND `productValues`.`product` = `products`.`id` 
         GROUP BY `products`.`id`"); 

$products = array(); 
while($r = mysql_fetch_assoc($result)) 
{ 
    $products[$r['id']] = $r; 
    $products[$r['id']]['values'] = explode(',', $products[$r['id']]['values']); 
} 
?> 

祝你好运!