2011-05-25 83 views
2

我有一個歷史記錄表。一個字段[添加]具有日期時間數據類型。我想要做的是選擇一個用戶最近的記錄,然後將它們從[added]字段派生出來的字符串進行分組。說它的值是2011-05-24 03:32:57.353,字符串是'Tuesday, May 24, 2011'。我想按該字符串對記錄進行分組,但是按實際時間排序子節點。我也想要一些自定義的XML輸出。SQL Server 2008 FOR XML PATH幫助

<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。

回答

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

我去發佈一個解決方案,看到你幾乎是一樣的。 ++爲你。 – 2011-05-25 03:15:30

+0

傑出!完美的作品。我有一個問題,是resD第二個公用表表達式?我看到resAll開始;用xxx作爲(),然後有一個逗號,並定義了resD。那是對的嗎?非常感謝這個偉大的解決方案。我確信FOR XML PATH是要走的路。 – Hcabnettek 2011-05-25 04:12:59

+1

@Hababnettek:是的,'resD'是第二個CTE,是的,這是正確的語法來定義多個CTE。 – 2011-05-25 04:40:15