2009-11-17 66 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或其他語言的結果集(可能是你返回數組一個數據庫程序)。