我有一张历史记录表。一个[添加]字段具有日期时间数据类型。我要做的是选择一个用户20个最近的记录,但然后按照从[添加]字段派生的字符串对它们进行分组。假设其值为2011-05-24 03:32:57.353
,字符串为'Tuesday, May 24, 2011'
。我想按该字符串对记录进行分组,然后按实际时间对子节点进行排序。我还想要一些自定义XML输出。
<ActivityHistory>
<Actvities foo="Tuesday, May 24, 2011">
<Activity id="10000" bar="zoo" bam="2011-05-24 03:32:57.353" />
<Activity id="10001" bar="zoo" bam="2011-05-24 03:31:57.353" />
<Activity id="10002" bar="zoo" bam="2011-05-24 03:28:57.353" />
<Activity id="10003" bar="zoo" bam="2011-05-24 03:21:57.353" />
</Activities>
<Actvities foo="Monday, May 23, 2011">
<Activity id="9990" bar="zoo" bam="2011-05-23 03:32:57.353" />
<Activity id="9989" bar="zoo" bam="2011-05-23 03:31:57.353" />
<Activity id="9988" bar="zoo" bam="2011-05-23 03:28:57.353" />
<Activity id="9987" bar="zoo" bam="2011-05-23 03:21:57.353" />
</Activities>
<Actvities foo="Sunday, May 22, 2011">
<Activity id="9900" bar="zoo" bam="2011-05-22 03:32:57.353" />
<Activity id="9899" bar="zoo" bam="2011-05-22 03:31:57.353" />
<Activity id="9898" bar="zoo" bam="2011-05-22 03:28:57.353" />
<Activity id="9897" bar="zoo" bam="2011-05-22 03:21:57.353" />
</Activities>
</ActivityHistory>
此有效负载始终只有0-20条记录。可能它总是20岁。
到目前为止,我的查询看起来像这样。
SELECT TOP 20
fnHistoryGroupingText(Added) [@foo]
FROM ActivityHistory
WHERE MricId = 1
GROUP BY fnHistoryGroupingText(Added)
FOR XML PATH ('Activities'), ROOT ('ActivityHistory')
它生成类似于我正在寻找的XML。
<ActivityHistory>
<Activities foo="Friday, May 20, 2011" />
<Activities foo="Monday, May 23, 2011" />
<Activities foo="Saturday, May 21, 2011" />
<Activities foo="Sunday, May 22, 2011" />
<Activities foo="Tuesday, May 24, 2011" />
</ActivityHistory>
请注意,它不是日期排序和缺少子节点。我希望他们按相反的时间顺序排序。我故意从查询中排除了一些字段,因为在查询的这一点上我有点得到我最终想要的结构。当我介绍其他领域时,XML已经过时了。分组文本是一个varchar,并不能很好地转换为日期。我可以以某种方式使用[添加]字段,但是当我将它包含在查询中时,它会破坏我的分组。有人能指出我正确的方向纠正这些问题吗? [A]正确编写查询,[B]告诉我如何正确输出我正在寻找的XML。
答案 0 :(得分:5)
试试这个:
/* INIT */
DECLARE @ActivityHistory TABLE (id int, bar VARCHAR(3), bam datetime)
INSERT INTO @ActivityHistory
SELECT id='10000', bar='zoo', bam='2011-05-24 03:32:57'
UNION SELECT id='10001', bar='zoo', bam='2011-05-24 03:31:57'
UNION SELECT id='10002', bar='zoo', bam='2011-05-24 03:28:57'
UNION SELECT id='10003', bar='zoo', bam='2011-05-24 03:21:57'
UNION SELECT id= '9990', bar='zoo', bam='2011-05-23 03:32:57'
UNION SELECT id= '9989', bar='zoo', bam='2011-05-23 03:31:57'
UNION SELECT id= '9988', bar='zoo', bam='2011-05-23 03:28:57'
UNION SELECT id= '9987', bar='zoo', bam='2011-05-23 03:21:57'
UNION SELECT id= '9900', bar='zoo', bam='2011-05-22 03:32:57'
UNION SELECT id= '9899', bar='zoo', bam='2011-05-22 03:31:57'
UNION SELECT id= '9898', bar='zoo', bam='2011-05-22 03:28:57'
UNION SELECT id= '9897', bar='zoo', bam='2011-05-22 03:21:57'
/* QUERY */
;WITH
resALL AS ( SELECT *
, foo = DATENAME(weekday, bam)+', '+ CONVERT(VARCHAR(30), bam, 107)
, food = CONVERT(VARCHAR(10), bam, 121)
FROM @ActivityHistory AS Activity
)
, resD AS ( SELECT DISTINCT foo, food FROM resALL
)
SELECT
Activities.foo
, (
SELECT id, bar, bam
FROM resALL AS Activity
WHERE foo = Activities.foo
ORDER BY bam desc
FOR XML AUTO, TYPE
)
FROM resD AS Activities
ORDER BY Activities.food DESC
FOR XML AUTO, TYPE, ROOT ('ActivityHistory')
/* OUTPUT
<ActivityHistory>
<Activities foo="Tuesday, May 24, 2011">
<Activity id="10000" bar="zoo" bam="2011-05-24T03:32:57" />
<Activity id="10001" bar="zoo" bam="2011-05-24T03:31:57" />
<Activity id="10002" bar="zoo" bam="2011-05-24T03:28:57" />
<Activity id="10003" bar="zoo" bam="2011-05-24T03:21:57" />
</Activities>
<Activities foo="Monday, May 23, 2011">
<Activity id="9990" bar="zoo" bam="2011-05-23T03:32:57" />
<Activity id="9989" bar="zoo" bam="2011-05-23T03:31:57" />
<Activity id="9988" bar="zoo" bam="2011-05-23T03:28:57" />
<Activity id="9987" bar="zoo" bam="2011-05-23T03:21:57" />
</Activities>
<Activities foo="Sunday, May 22, 2011">
<Activity id="9900" bar="zoo" bam="2011-05-22T03:32:57" />
<Activity id="9899" bar="zoo" bam="2011-05-22T03:31:57" />
<Activity id="9898" bar="zoo" bam="2011-05-22T03:28:57" />
<Activity id="9897" bar="zoo" bam="2011-05-22T03:21:57" />
</Activities>
</ActivityHistory>
*/