【问题标题】:mySQL: Subquery to array?mySQL:数组的子查询?
【发布时间】:2010-12-01 14:22:42
【问题描述】:

我正在处理一个稍微复杂的(至少对我而言)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] => 
        )
)

我想要的是 values 元素也成为一个数组,其中包含 Values 表中匹配的所有元素 (WHERE productValues.product = product.id)。

我做错了什么?

【问题讨论】:

    标签: mysql subquery


    【解决方案1】:

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

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

    【讨论】:

    • 只有当 GROUP_CONCAT 保证产生一个
    • @dnagirl - 你可以随时增加group_concat_max_len.的大小,group_concat 很方便。不必编写代码来迭代结果,因此可以尽早释放mysql结果
    • @ajreal:我同意GROUP_CONCAT 很方便。但是即使更改group_concat_max_length,仍然存在限制,并且该限制会咬你。我有T恤来证明这一点。 ;)
    • @dnagirl - 是的,限制永远是限制。只是无法抗拒来自 group_concat 的诱惑。
    【解决方案2】:
    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 提供一个包含一行的表(顺便说一句,不建议使用保留字如 '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'];
    }
    

    我给出的结构可能比您要求的结构更灵活,因为它允许您通过数组键访问特定产品。

    【讨论】:

      【解决方案3】:

      我认为“值”属性将始终是一个变量。想想纯 SQL,不管 PHP - 如果您在 sql 编辑器中运行类似的查询 - 您会得到 values 属性作为一列。如果您要求检索多于一列,您将得到一个错误。
      通常,SQL 查询总是平坦的 - 一层。
      我的建议 - 运行 2 个查询,并将它们放在 PHP 层中。

      【讨论】:

        【解决方案4】:

        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']);
        }
        ?>
        

        祝你好运!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-04
          • 2015-09-11
          • 1970-01-01
          相关资源
          最近更新 更多