2012-03-08 128 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的情况下做的是创造一个支点与列的任意数量(认为肯定将是很好!)