我有一个我试图查询的XML字段。我想出了如何返回第一项,第二项等。我需要弄清楚如何根据日期过滤器返回项目。日期包含在XML字段中,但我无法确定格式。以下是名为[AMOUNT]的XML字段示例。
<X C="1" I="0">
<E D="0Y56M0W0D" P="0" A="122039" />
<E D="0Y10M0W0D" P="0" A="125739" />
<E D="1000Y0M0W0D" P="1" A="131739" />
</X>
我可以使用以下查询来查询指定要返回的项目。
SELECT
cast(AMOUNT as XML).value('(/X/E)[1]/@A','varchar(10)') AS [TEST],
cast(AMOUNT as XML).value('(/X/E)[2]/@A','varchar(10)') AS [TEST2],
cast(AMOUNT as XML).value('(/X/E)[3]/@A','varchar(10)') AS [TEST3]
FROM MEASURE
我需要帮助找到一种方法来返回在特定日期生效的[AMOUNT],让我们说2016-11-01。下面是前端显示数据的内容。还有一个[STARTDATE]字段,在这种情况下它等于2012-01-01。
DATE | MONTH | AMOUNT |
2012-01-01 | 1| 122039|
2016-09-01 | 57| 125739|
2017-07-01 | 67| 131739|
我需要帮助编写查询以拉出[AMOUNT] 125,739作为2016-11-01的日期过滤器。任何帮助将不胜感激。我使用的是SQL Server 2008。
答案 0 :(得分:1)
这似乎是问题的解决方案这是如何解释的?但尚未解决实际问题我应该如何在过滤器中使用它?。一旦您了解了如何阅读本文,您是否需要帮助?
DECLARE @d1 DATETIME={d'2012-01-01'};
DECLARE @d2 DATETIME=(SELECT DATEADD(MONTH,56,@d1));
DECLARE @d3 DATETIME=(SELECT DATEADD(MONTH,10,@d2));
SELECT @d1,@d2,@d3;
字符串 D =&#34; 0Y56M0W0D&#34; 似乎将 D 指向下一个日期。 字符串 D =&#34; 0Y10M0W0D&#34; 是以下的 D ,并且 D =&#34; 1000Y0M0W0D 指向我是最后一个,因为没有人在困扰1000年后发生的事情!
一些提示
CHARINDEX
和SUBSTRING
可以选择字母 Y,M,W和D 之间的数字。 decimal
。当您使用SQL-Server 2008时,您无法使用累积SUM() OVER()
,这就是为什么我使用递归CTE遍历您的日期并将距离添加到上一行的日期。
试试这个:
DECLARE @xml XML=
N'<X C="1" I="0">
<E D="0Y56M0W0D" P="0" A="122039" />
<E D="0Y10M0W0D" P="0" A="125739" />
<E D="1000Y0M0W0D" P="1" A="131739" />
</X>';
DECLARE @StartDate DATETIME={d'2012-01-01'};
- 这是第一次CTE
WITH Shredded AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS SortNr
,D.Dist AS Distance
,e.value('@P','int') AS P
,CAST(e.value('@A','int') AS DECIMAL(10,4))/1000 AS Amount
,CAST(SUBSTRING(D.Dist,1,PosY-1) AS INT) AS Y
,CAST(SUBSTRING(D.Dist,PosY+1,PosM-PosY-1) AS INT) AS M
,CAST(SUBSTRING(D.Dist,PosM+1,PosW-PosM-1) AS INT) AS W
,CAST(SUBSTRING(D.Dist,PosW+1,PosD-PosW-1) AS INT) AS D
FROM @xml.nodes('/X/E') AS A(e)
CROSS APPLY (SELECT e.value('@D','nvarchar(100)') AS Dist) AS D
CROSS APPLY(SELECT CHARINDEX('Y',D.Dist) AS PosY
,CHARINDEX('M',D.Dist) AS PosM
,CHARINDEX('W',D.Dist) AS PosW
,CHARINDEX('D',D.Dist) AS PosD
) AS Positions
)
- 递归CTE
,RecCTE AS
(
SELECT @StartDate AS ActualDate,*
FROM Shredded
WHERE SortNr=1
UNION ALL
SELECT DATEADD(YEAR,r.Y,DATEADD(MONTH,r.M,DATEADD(WEEK,r.W,DATEADD(DAY,r.D,r.ActualDate))))
,s.*
FROM RecCTE AS r
INNER JOIN Shredded AS s ON s.SortNr=r.SortNr+1
)
- 最后的查询
SELECT * FROM RecCTE
+-------------------------+--------+-------------+---+---------------+------+----+---+---+
| ActualDate | SortNr | Distance | P | Amount | Y | M | W | D |
+-------------------------+--------+-------------+---+---------------+------+----+---+---+
| 2012-01-01 00:00:00.000 | 1 | 0Y56M0W0D | 0 | 122.039000000 | 0 | 56 | 0 | 0 |
+-------------------------+--------+-------------+---+---------------+------+----+---+---+
| 2016-09-01 00:00:00.000 | 2 | 0Y10M0W0D | 0 | 125.739000000 | 0 | 10 | 0 | 0 |
+-------------------------+--------+-------------+---+---------------+------+----+---+---+
| 2017-07-01 00:00:00.000 | 3 | 1000Y0M0W0D | 1 | 131.739000000 | 1000 | 0 | 0 | 0 |
+-------------------------+--------+-------------+---+---------------+------+----+---+---+