2014-07-23 32 views
0

我想從我的數據庫的三個表中創建XML導出。PostgreSQL - 如何呈現更多的一對多關係到XML

表:客戶,訂單,付款。當然,一個客戶可能會有更多的訂單和更多的付款。

我已經在stackoverflow上看到了這個很棒的話題:「How to render one to many relationships to XML with PostgreSQL",它幫助我瞭解瞭如何構建查詢,但是,只有當我將表Customers連接到Orders或。付款,而不是他們兩個我沒有找到如何構建查詢,所以我在模型中像這樣得到的輸出:

<Customer> 
<Name/> 
<Orders> 
    <Order> 
     <id/> 
     <date/> 
     <content/> 
    </Order> 
</Orders> 
<Payments> 
    <Payment> 
     <id/> 
     <date/> 
     <amount/> 
    </Payment> 
</Payments> 
</Customer> 

試圖做到這一點是這樣的:

SELECT xmlelement(name "Customer", 
        xmlelement(name "Name", c.name), 
     xmlelement(name "Orders", 
      xmlagg(xmlelement(name "Order", 
         xmlelement(name "id", o.id),      
         xmlelement(name "date", o.date), 
         xmlelement(name "content", o.content)))), 
     xmlelement(name "Payments",       
      xmlagg(xmlelement(name "Payment", 
         xmlelement(name "id", p.id),       
         xmlelement(name "date", p.date), 
         xmlelement(name "amount", p.amount))))) 
from customers c 
left join orders o on c.id = o.c_id 
left join payments p on c.id = p.c_id 
group by c.id, c.name; 

...沒有意義。如果客戶有實例e 5訂單和3付款,它返回15行的表格。所以有15個訂單和15個支付。我不知道如何以正確的方式使用xmlaagg()函數。作爲使用XML的新手,我甚至不知道是否有可能以所需的方式從數據庫創建輸出。

我會很感激任何幫助。

樣本數據: (這實際上只是一個簡單的例子,假設訂單和付款之間沒有關係,在我的真實項目中還有其他項目並沒有關係,我需要查看所有付款和所有付款訂單)。

CREATE TEMPORARY TABLE customers 
(
    id  int, 
    name text 
); 

CREATE TEMPORARY TABLE orders 
(
    id  int, 
    c_id int, -- customer ID 
    date date, 
    content text 

); 

CREATE TEMPORARY TABLE payments 
(
    id  int, 
    c_id int, -- customer ID 
    date date, 
    amount numeric 
); 

INSERT INTO customers 
VALUES(1, 'someguy'); 

INSERT INTO orders 
VALUES 
(1, 1, '1.1.2001', 'noteboook'), 
(2, 1, '2.1.2001', 'tablet'), 
(3, 1, '3.1.2001', 'phone'), 
(4, 1, '3.1.2001', 'bag'), 
(5, 1, '3.1.2001', 'shoes'); 

INSERT INTO payments 
VALUES 
(1, 1, '1.2.2001', '100'), 
(2, 1, '2.2.2001', '200'), 
(3, 1, '3.2.2001', '300'); 

-- DROP TABLE payments; 
-- DROP TABLE orders; 
-- DROP TABLE customers; 
+0

那麼,它明確會。但不幸的是,我現在只能應付SQL。我知道,最後是學習一些編程語言的時候了。 – Trocader

+0

對不起,出於某種原因,我認爲你正在使用類似Ruby的東西。在今天看過太多的其他帖子,對不起。忽略我的評論。 –

+0

感謝您的反應! – Trocader

回答

0

是必要的聚合前加入

select 
    xmlelement(name "Customer", 
     xmlelement(name "Name", name), 
     orders, payments 
    ) as the_xml 
from 
    customers 
    left join (
     select c_id as id, 
     xmlelement(name "Orders", 
      xmlagg(xmlelement(name "Order", 
       xmlelement(name "id", id),      
       xmlelement(name "date", date), 
       xmlelement(name "content", content) 
       ) 
      ) 
     ) as orders 
     from orders 
     group by c_id 
    ) o using (id) 
    left join (
     select c_id as id, 
     xmlelement(name "Payments",       
      xmlagg(xmlelement(name "Payment", 
       xmlelement(name "id", id),       
       xmlelement(name "date", date), 
       xmlelement(name "amount", amount) 
       ) 
      ) 
     ) as payments 
     from payments 
     group by c_id 
    ) p using (id) 
+0

嗚呼!真棒!非常感謝你,我永遠不會自己找到解決方案,可能,我以前努力過,但現在看來我很清楚!你幫了我很多,歡呼! – Trocader