【问题标题】:SQL Server 2008 FOR XML PATH helpSQL Server 2008 FOR XML PATH 帮助
【发布时间】:2011-05-25 01:11:02
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    试试这个:

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

    【讨论】:

    • 我发布了一个解决方案,发现您的解决方案几乎相同。 ++ 为您服务。
    • 优秀!!完美运行。我有一个问题, resD 是第二个公用表表达式吗?我看到 resAll 开始 ;with xxx as (),然后有一个逗号,并且定义了 resD。那是对的吗?非常感谢您提供的出色解决方案。我确信 FOR XML PATH 是要走的路。
    • @Hcabnettek:是的,resD 是第二个 CTE,是的,这是定义多个 CTE 的正确语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多