2009-11-17 65 views
0

我有一个sql查询从不同的表中抽取一些结果,其中一个表 - “orders” - 包含客户详细信息,其中包含一个order_id作为PK,另一个表 - order_products - 包含每个订购的产品,并参考order_id和另一列为PK。存储在数组中的SQL嵌套查询?

基本上,我需要知道如何以这样的方式查询数据库,即每个order_id只显示一次,即使同一行中添加了order_products表中的数据,即使客户已订购了多个产品特定的顺序。正在重复

目前客户详细信息的结果中,如果他们已经订购了多种不同的产品 - 我知道为什么发生这种情况(见查询),但不知道如何在需要的格式结果输出。我最好的想法是嵌套查询,其中order_products的结果被加载到数组或其他东西,但我甚至不知道这是否可能。

我正在使用MySQL和PHP的结果,然后在XML文档中输出。如果您需要更多信息,请询问!

SELECT uc_orders.order_id, uc_orders.order_total, uc_orders.primary_email, 
    uc_orders.delivery_first_name, uc_orders.delivery_last_name, 
    uc_orders.delivery_street1, uc_orders.delivery_street2, uc_orders.delivery_city, 
    uc_orders.delivery_zone, uc_orders.delivery_postal_code, uc_zones.zone_name, 
    uc_order_products.title, uc_order_products.price 
    FROM uc_orders 
    LEFT JOIN uc_zones ON uc_orders.delivery_zone = uc_zones.zone_id 
    LEFT JOIN uc_order_products ON uc_orders.order_id = uc_order_products.order_id 
    ORDER BY order_id 

回答

3

关系数据库的一个基本原则是列不包含复合数据,这意味着没有数组。它也被称为“first normal form”(1NF)。如果您不想在产品查询中重复订购信息,则可以运行两个查询,而不是一个查询,一个查询订单,另一个查询产品。

由于查询的结果正在处理反正,你还可以在PHP中照顾聚集,一旦你得到的结果。可以先聚合:

$orders=array(); 
while ($row = $result->fetch()) { 
    if (! isset($orders[$row['order_id']])) { 
     $orders[$row['order_id']] = new Order($row); 
    } else { 
     $orders[$row['order_id']]->addProducts($row); 
    } 
} 

(假设一个合适的顺序类),或聚集在线方式:

class OrderList { 
    ... 
    function printXML($result) { 
     $currOrderID = null; 
     echo '<orders>' 
     while ($row = $result->fetch()) { 
      if ($currOrderID != $row['order_id']) { 
       $this->closeOrder(); 
       $this->openOrder($row); 
      } 
      $this->printProduct($row); 
     } 
     $this->closeOrder(); 
     echo '</orders>'; 
    } 

    function openOrder($row) { 
     echo "<order id='$row[order_id]'><total>$row[order_total]</total>"; 
     $this->printCustomer($row); 
     echo '<products>'; 
    } 

    function printProduct($row) { 
     echo "<product><title>$row[title]</title><price>$row[price]</price></product>\n"; 
    } 

    function closeOrder() { 
     echo '</products></order>'; 
    } 

    function printCustomer($row) { 
     echo <<EOS; 
      <customer> 
      <email>$row[primary_email]</email> 
      <first_name>$row[delivery_first_name]</first_name> 
      ... 
EOS; 
     $this->printAddress($row); 
     echo '</customer>'; 
    } 

    function printAddress($row) { 
     echo <<EOS; 
      <address> 
      <street line="1">$row[delivery_street1]</street> 
      <street line="2">$row[delivery_street2]</street> 
      ... 
      </address> 
EOS; 
    } 
} 

当然,上述的具体细节不是用于生产代码良好的设计。该print*方法(甚至是为了打印,通过openOrdercloseOrder)是活该要OrderWriter,CustomerWriter,AddressWriter和ProductWriter类。您可能还想使用XMLWriter而不是回显。

+0

感谢您的详细回复 - 我使用DOM来照顾XML的东西。我会适应你的例子来适应我的项目。 艾伦 – Allan 2009-11-17 16:53:35

+0

请把我的建议写成心灵的作家类。我很想改变这个例子。 – outis 2009-11-17 17:20:25

0

您可以创建一个用户定义函数将接受订单ID和一个字符串返回订购产品的列表。然后,您只需调用UDF,而不是加入您的uc_order_products表。希望这可以帮助。

0

这是一个程序性的任务,需要处理使用PHP或其他语言的结果集(可能是你返回数组一个数据库程序)。