2014-03-06 91 views
2

我正在嘗試使用Altova XMLSpy和XQuery 1.0爲每個客戶返回最近的訂單。XQuery每個客戶的最近訂單

在SQL查詢是這樣的:

SELECT `Order ID`, `Customer ID`, `Employee ID`, `Order Date` 
FROM Orders AS O1 
WHERE `Order Date` = 
    (SELECT MAX(`Order Date`) 
    FROM Orders AS O2 
    WHERE O2.[Customer ID] = O1.[Customer ID]); 

它返回16行,但我不能讓類似的XQuery中工作的任何東西。

我已經試過多個代碼變化,我想我已經得到了最接近的是這樣的:

<result> 
{ 
    for $cust in distinct-values(doc("Orders.xml")//Orders/Customer_x0020_ID) 
    return 
    <Customer> 
    { 
     for $order in doc("Orders.xml")//Orders 
     where $cust = $order/Customer_x0020_ID 
     return max(xs:string($order/Order_x0020_Date)) 

    } 
    </Customer> 

} 
</result> 

道歉的XML已經從MS Access導出的可怕的標籤名稱。

請幫忙!提前致謝。

<Orders> 
    <Order_x0020_ID>30</Order_x0020_ID> 
    <Employee_x0020_ID>9</Employee_x0020_ID> 
    <Customer_x0020_ID>27</Customer_x0020_ID> 
    <Order_x0020_Date>2006-01-15T00:00:00</Order_x0020_Date> 
</Orders> 

編輯: 試圖joemfb的解決方案後,我收到的所有訂單爲每一個客戶時,我只需要最近(或最大日期):

<Customer> 
    <Order_x0020_ID>57</Order_x0020_ID> 
    <Customer_x0020_ID>27</Customer_x0020_ID> 
    <Employee_x0020_ID>9</Employee_x0020_ID> 
    <Order_x0020_Date>2006-04-22T00:00:00</Order_x0020_Date> 
    <Order_x0020_ID>30</Order_x0020_ID> 
    <Customer_x0020_ID>27</Customer_x0020_ID> 
    <Employee_x0020_ID>9</Employee_x0020_ID> 
    <Order_x0020_Date>2006-01-15T00:00:00</Order_x0020_Date> 
</Customer> 
<Customer> 
    <Order_x0020_ID>80</Order_x0020_ID> 
    <Customer_x0020_ID>4</Customer_x0020_ID> 
    <Employee_x0020_ID>2</Employee_x0020_ID> 
    <Order_x0020_Date>2006-04-25T17:03:55</Order_x0020_Date> 
    <Order_x0020_ID>58</Order_x0020_ID> 
    <Customer_x0020_ID>4</Customer_x0020_ID> 
    <Employee_x0020_ID>3</Employee_x0020_ID> 
    <Order_x0020_Date>2006-04-22T00:00:00</Order_x0020_Date> 
    <Order_x0020_ID>61</Order_x0020_ID> 
    <Customer_x0020_ID>4</Customer_x0020_ID> 
    <Employee_x0020_ID>9</Employee_x0020_ID> 
    <Order_x0020_Date>2006-04-07T00:00:00</Order_x0020_Date> 
    <Order_x0020_ID>34</Order_x0020_ID> 
    <Customer_x0020_ID>4</Customer_x0020_ID> 
    <Employee_x0020_ID>9</Employee_x0020_ID> 
    <Order_x0020_Date>2006-02-06T00:00:00</Order_x0020_Date> 
    <Order_x0020_ID>31</Order_x0020_ID> 
    <Customer_x0020_ID>4</Customer_x0020_ID> 
    <Employee_x0020_ID>3</Employee_x0020_ID> 
    <Order_x0020_Date>2006-01-20T00:00:00</Order_x0020_Date> 
</Customer> 
+1

請始終給出示例數據來處理。由於對數據的誤解,其他一切都會導致一系列後續問題。 –

+2

你在用什麼具體的數據庫?他們都說「SQL」作爲他們的查詢語言 - 但像XML支持這樣的東西在供應商和供應商之間差別很大。因此,請使用您正在使用的具體數據庫更新您的代碼 - 無論是MySQL,Postgres,Sybase,IBM DB2,Oracle,SQL Server,Interbase,還是您正在使用的任何其他應用程序! –

+1

對於我使用MS Access的SQL,但XQuery沒有使用數據庫,查詢是從獨立XML文檔(現在我已經提供了一個片段)在Altova XMLSpy中運行 – dinkydani

回答

2

更新:我已經修改查詢以僅返回最近訂單的所有元素。這個查詢有點尷尬,因爲您的源XML不按順序對元素進行分組。

<result> 
{ 
    for $cust in distinct-values(doc("Orders.xml")//Orders/Customer_x0020_ID) 
    return 
    <Customer> 
    { 
     let $date := 
     (
     for $cid in doc("Orders.xml")//Orders/Customer_x0020_ID[. eq $cust] 
     let $date := $cid/following-sibling::Order_x0020_Date[1] 
     order by xs:dateTime($date) descending 
     return $date 
    )[1] 
     return 
     (
     $date/preceding-sibling::Order_x0020_ID[1], 
     $date/preceding-sibling::Customer_x0020_ID[1], 
     $date/preceding-sibling::Employee_x0020_ID[1], 
     $date 
    ) 
    } 
    </Customer> 
} 
</result> 
+0

除了原始的SQL查詢返回'訂單ID','客戶ID','員工ID','訂單日期',而這隻返回日期。 –

+0

謝謝,我錯過了;我已更新我的示例。 – joemfb

+0

唉,但它會返回每個客戶的所有訂單(將用數據更新我的問題)。我只需要每個客戶的最近訂單,這是我遇到麻煩的原因:( – dinkydani

1

XQuery 3.0解決方案。

一個高階函數類似撒克遜:最高()都可以在這裏有用:看

http://www.saxonica.com/documentation/#!functions/saxon/highest

有了這樣的功能,代碼變成類似如下(我假設「樣本數據中的訂單」元素代表了一個訂單,並重復):

for $o in //Orders 
group by $o/Customer_ID 
return saxon:highest($o, function($order){xs:date($order/Order_Date)}) 

如果你不使用撒克遜你可以寫撒克遜:最高()函數自己,像這樣:

declare function saxon:highest($s as item()*, $f as function(item()*) as xs:anyAtomicValue) as item()?{ 
    if (count($s) lt 2) 
    then head($s) 
    else (
     let $h := saxon:highest(tail($s), $f) 
     return if ($f(head($s)) gt $f($h)) 
      then head($s) 
      else $h 
} 
相關問題