SQL查询xml输出

时间:2013-11-24 05:28:25

标签: sql sql-server xml tsql

我有一个查询,我正在我的页面上运行一些搜索结果。存储过程如下所示:

BEGIN
SET NOCOUNT ON;
BEGIN
    SELECT *
    FROM   (SELECT id,
                   data,
                   dataType,
                   dataLocation,
                   tag,
                   whoAdded,
                   whenAdded,
                   notes,
                   ROW_NUMBER() OVER (PARTITION BY data ORDER BY whenAdded DESC) AS rn
            FROM   Tags_Accounts
            WHERE  tag IN (SELECT *
                           FROM   dbo.splitstring (@tags))) AS a
    WHERE  rn = 1
    FOR    XML PATH ('results'), TYPE, ELEMENTS, ROOT ('root');
END
END

这将通过我的记录,如下所示:

enter image description here

现在,如果我要搜索标签内容,paypal它应该返回2个结果,因为分区在数据列上。

结果的XML输出如下:

            <root>
              <results>
                <id>43</id>
                <data>123333</data>
                <dataType>1</dataType>
                <dataLocation>AF</dataLocation>
                <tag>paypal</tag>
                <whoAdded>chussey</whoAdded>
                <whenAdded>2013-11-22T11:01:50.117</whenAdded>
                <rn>1</rn>
              </results>
              <results>
                <id>41</id>
                <data>12345</data>
                <dataType>1</dataType>
                <dataLocation>AF</dataLocation>
                <tag>paypal</tag>
                <whoAdded>chussey</whoAdded>
                <whenAdded>2013-11-22T10:59:39.277</whenAdded>
                <rn>1</rn>
              </results>
              <results>
                <id>50</id>
                <data>RGG</data>
                <dataType>2</dataType>
                <dataLocation>AF</dataLocation>
                <tag>stuff</tag>
                <whoAdded>chussey</whoAdded>
                <whenAdded>2013-11-22T22:25:41.393</whenAdded>
                <rn>1</rn>
              </results>
            </root>

它包括PayPal的2个结果,因为数据col中的数据不同。它返回了1条记录,因为数据已经在标签PayPal的结果中找到匹配。

我的问题:有没有办法完全按照现在的做法进行,但在<Tag></Tag>中包含与数据列中的数据匹配的所有标记?

例如,由于找到了标记stuff与另一个标记Paypal,因此它会将它们包含在一起。

这样做的目的是找到包含搜索标签的任何数据。如果找到它并且该数据的标签超过1个,它将包含所有标签。

<results>
    <id>50</id>
    <data>RGG</data>
    <dataType>2</dataType>
    <dataLocation>AF</dataLocation>
    <tag>stuff, testing</tag>
    <whoAdded>chussey</whoAdded>
    <whenAdded>2013-11-22T22:25:41.393</whenAdded>
    <rn>1</rn>
</results>

1 个答案:

答案 0 :(得分:0)

我认为这样做是你想要的:

WITH OrderedTags
AS
(
    SELECT  id,
            data,   
            dataType,
            dataLocation,
            CAST(tag as NVARCHAR(max)) as tag,
            whoAdded,
            whenAdded,
            notes,
            ROW_NUMBER() OVER (PARTITION BY data ORDER BY tag, id) AS rn
    FROM    Tags_Accounts T
)
,RecurseTags (data, tags, rn)
AS
(
--Anchor
    SELECT  data,
            tag as tags,
            rn
    FROM    OrderedTags T
    WHERE   rn = 1
    UNION ALL
--Recurse
    SELECT  R.data,
            tags + N', ' + tag,
            T.rn
    FROM    RecurseTags R
    JOIN    OrderedTags T
        ON  T.data = R.data
        AND T.rn = R.rn + 1
)
,CommaSeparatedTags(data, tags)
AS
(
    SELECT  data, tags
    FROM
    (
        SELECT  data,
                tags,
                ROW_NUMBER() OVER (PARTITION BY data ORDER BY rn DESC) AS rn
        FROM    RecurseTags
    ) T
    WHERE rn = 1
)
,RequiredRows
AS
(
    SELECT * FROM(
    SELECT  A.id,
            A.data, 
            A.dataType,
            A.dataLocation,
            C.tags as tag,
            A.whoAdded,
            A.whenAdded,
            A.notes,
            ROW_NUMBER() OVER (PARTITION BY A.data ORDER BY A.whenAdded DESC) AS rn
    FROM   OrderedTags A
    JOIN   dbo.splitstring (@tags) T
        ON T.Value = A.tag
    JOIN    CommaSeparatedTags C
        ON C.data = A.data) A
    WHERE rn = 1
)
SELECT * FROM RequiredRows
FOR    XML PATH ('results'), TYPE, ELEMENTS, ROOT ('root')

基本上,它按数据对标签进行排序,生成统一表,然后将原始查询加入到...