我的查询返回所有拨打的电话。我需要将返回的XML值分成4列:
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
有时会返回:
所以我的返回查询应该看起来像下面的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 :(得分:1)
内置的XML解析器允许您将XML转换回行而不是列。您唯一可以做的就是基本上“撤消”XML聚合。请参阅SQL Server中的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的上下文中你无法做的是创建一个具有任意数量列的数据透视图(认为肯定会很好!)
答案 1 :(得分:0)
您正在使用XML按帐户汇总数据。我想你完全避免使用XML并使用ROW_NUMBER()OVER()构造来获取每个帐户的日期范围内的最后4个调用,然后使用PIVOT运算符进行透视。