2010-12-01 93 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']); 
} 
?> 

祝你好運!