SQL Server 2008 FOR XML 路径帮助

标签 sql sql-server xml sql-server-2008 for-xml

我有一个历史记录表。 [添加] 一个字段具有日期时间数据类型。我想要做的是选择用户 20 个最近的记录,然后按从 [added] 字段派生的字符串对它们进行分组。假设其值为 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 并且不能很好地转换为日期。我可以以某种方式使用 [added] 字段,但是当我将其包含在查询中时,它会破坏我的分组。谁能指出我纠正这些问题的正确方向? [A] 正确编写查询,并且 [B] 向我展示如何正确输出我正在查找的 XML。

最佳答案

试试这个:

/*  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>
*/

关于SQL Server 2008 FOR XML 路径帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6118538/

相关文章:

sql - Postgres 将时间戳列约束从 NOT NULL 更改为 NULL

sql - 将两个单独查询的结果合并到两列中

javascript - 无法使用命名空间和 javascript 解析 Xml

sql-server - 订单管理的数据库设计

java - 如何在 Java 中生成 XML(以字符串表示形式)

.net XSLT 创建工作表

c# - ExecuteNonQuery() 抛出 "Incorrect syntax near the keyword ' 用户'”

c# - 有什么好的方法可以防止SQL注入(inject)?

sql - 使用名为 "external"的表

sql - 参数化 SQL 中的子查询