2014-03-06 5 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를 사용하고 있지만 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)}) 

당신이 색슨를 쓸 수 색슨을 사용하지 않는 경우 : 다음과 같이 자신을 기능) 가장 높은 (:

를 0
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 
}