2012-03-08 75 views
0

我的查詢返回所有調用。我需要將返回的XML值分爲4列:將SQL XML解析回SQL列

FirstCallDate,SecondCallDate,ThirdCallDate,LastCallDate。

當前查詢:

SELECT AllCalls FROM 
(
SELECT 
      ( SELECT startdate 
      FROM mycalls i WITH (NOLOCK) WHERE i.phone = d.phone FOR XML AUTO) 
      AS AllCalls 

    FROM [MYDB].[dbo].[Accounts] d WITH (NOLOCK) 
    WHERE SubmittedDate BETWEEN @MyStartDate AND @MyEndDate 

) e 

這有時會返回:

  • NULL
  • 我STARTDATE = 「2012-02-29T13:50:37」/>
  • 我startdate =「2012-02-29T14:20:58」/> i startdate =「2012-02-29T14:21:13」/>(刪除開始括號)
  • 3 +日期
  • 4 +紅棗
  • 5 +紅棗

所以我回來查詢應該看起來像下面的SQL,但每列應該只持有1個日期。

SELECT FirstCallDate, SecondCallDate, ThirdCallDate, LastCallDate 
FROM 
    (
    SELECT 
       ( SELECT startdate 
       FROM mycalls i WITH (NOLOCK) WHERE i.phone = d.phone FOR XML AUTO) 
       AS AllCalls 

     FROM [MYDB].[dbo].[Accounts] d WITH (NOLOCK) 
     WHERE SubmittedDate BETWEEN @MyStartDate AND @MyEndDate 

    ) e 

關於如何將XML解析回SQL列的任何想法?

回答

0

您正在使用XML按帳戶聚合數據。我認爲你完全避免使用XML,並使用ROW_NUMBER()OVER()結構來獲取每個賬戶在日期範圍內的最後4次調用,然後使用PIVOT運算符進行調整。

1

內置的XML解析器允許您將XML轉換回行,而不是列。你可以做的唯一可能的事情是基本上「撤銷」XML聚合。請參閱SQL服務器中的XML主題:http://msdn.microsoft.com/en-us/library/ms189887.aspx。這個我用於名稱空間參考的子主題:http://msdn.microsoft.com/en-us/library/ms177400.aspx

從那裏您可以按照您的要求轉動結果。我已經適應您的查詢做到這一點:

WITH XMLNAMESPACES ('uri' as ns1) 
SELECT phone, [1] AS FirstCall, [2] As SecondCall, [3] As ThirdCall, [4] As LastCall 
FROM (SELECT RN, phone, IndexRef 
     FROM (SELECT phone, CAST((SELECT StartDate as 'ns1:StartDate' 
         FROM mycalls i WITH (NOLOCK) WHERE i.phone = d.phone FOR XML RAW('ns1:Prod'), ELEMENTS) AS XML) AS AllCalls 
       FROM [mydb].[dbo].[Accounts] d 
       WHERE phone in (31304,35549,39794,42711,51201,52529)) ns1 
       CROSS APPLY (SELECT row_number() over (order by relop.value('.','DateTime')) RN, relop.value('.','DateTime') AS CallLog 
           FROM ns1.AllCalls.nodes(N'//ns1:StartDate') AS ro(relop)) r) X 
     PIVOT(MAX(CallLog) FOR RN IN ([1],[2],[3],[4])) P 

顯然,對於這個查詢中,XML是簡單地在中間臃腫,可以跳過(查詢之後)。儘管如此,如果您將某個源的XML輸出綁定到直接查詢之外,則此方法非常有用。

如果不使用XML,則更容易。

SELECT P.phone, p.[1] AS FirstCallDate, p.[2] AS SecondCallDate, p.[3] AS ThirdCallDate, p.[4] AS LastCallDate 
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY i.phone ORDER BY i.StartDate) i.phone, CallOrder, StartDate 
     FROM [mydb].[dbo].[Accounts] d 
       JOIN mycalls i ON d.phone = i.phone 
     WHERE d.SubmittedDate BETWEEN @MyStartDate AND @MyEndDate) X 
     PIVOT (MAX(StartDate) FOR CallOrder IN ([1], [2], [3], [4])) P 

,你將不能夠在SQL的情況下做的是創造一個支點與列的任意數量(認爲肯定將是很好!)