-3

我有一个看起来像这样的数据集:

   Gender | Age | Name
    Male  | 30  | Bill
  Female  | 27  | Jenny
  Female  | 27  | Debby 
   Male   | 44  | Frank

我正在尝试将其显示为特殊格式的 HTML 代码:

    <ul>
      <li>Male
        <ul>
          <li>30
            <ul>
              <li>Bill</li>
            </ul>
          </li>
          <li>44
            <ul>
              <li>Frank</li>
            </ul>
          </li>
        </ul>  
      </li>
    </ul>

    <ul>
      <li>Female
        <ul>
          <li>27
            <ul>
              <li>Jenny</li>
              <li>Debby</li>
            </ul>
          </li>
        </ul>  
      </li>
    </ul>

我尝试使用FOR XML,但这并没有给出我想要的结果。它没有删除返回的多个GenderAge字段。正如您在此 HTML 中看到的那样,它将所有内容组合在一起,并且仅在结束节点处给出重复项。

Aaron Bertrand 在这里提供了一个很好的方法Return Select Statement as formatted HTML,它似乎在 SQL 2008 中完美运行,但我一直在寻找在 2005 年也能正常工作的东西,除了一些小东西,比如+=运算符和设置默认 DECLARE 值,只是没有2005 年不显示。

在 SQL Server 2005 中如何实现这样的功能?

4

3 回答 3

5
declare @T table
(
  Gender varchar(10),
  Age int,
  Name varchar(10)
)

insert into @T values ('Male',   30,   'Bill')
insert into @T values ('Female', 27,   'Jenny')
insert into @T values ('Female', 27,   'Debby') 
insert into @T values ('Male',   44,   'Frank')

select Gender as 'li',
       (select T2.Age as 'li',
               (select T3.Name as 'li'
                from @T as T3
                where T2.Age = T3.Age and
                      T1.Gender = T3.Gender
                for xml path(''), root('ul'), type) as 'li'
        from @T as T2
        where T1.Gender = T2.Gender
        group by T2.Age
        for xml path(''), root('ul'), type) as 'li'
from @T as T1
group by Gender
for xml path('ul')
于 2012-04-24T15:33:42.070 回答
4

这是 SQL Server 2005 的代码,它只需要对我昨天给出的答案进行细微调整,该答案是专门针对 SQL Server 2008 要求的:

DECLARE @x TABLE(Gender VARCHAR(6), Age INT, Name VARCHAR(32));

INSERT @x SELECT 'Male',   30, 'Bill'  UNION ALL SELECT 'Female', 27, 'Jenny'
UNION ALL SELECT 'Female', 27, 'Debby' UNION ALL SELECT 'Male',   44, 'Frank';

DECLARE @html NVARCHAR(MAX);
SET @html = N'';

;WITH x AS ( SELECT x.Age, x.Gender, x.Name,
    dr = DENSE_RANK() OVER (PARTITION BY x.Gender ORDER BY x.Age),
    gn = ROW_NUMBER() OVER (PARTITION BY x.Gender ORDER BY x.Age),
    rn = ROW_NUMBER() OVER (ORDER BY x.Gender DESC, x.Age)
  FROM @x AS x ) SELECT @html = @html + 
    CHAR(13) + CHAR(10) + CASE WHEN c1.gn = 1 THEN 
        CASE WHEN c1.rn > 1 THEN '</li></ul></li></ul>' ELSE '' END + '<ul><li>' 
        + c1.Gender ELSE '' END + CHAR(13) + CHAR(10) + CHAR(9) 
        + CASE WHEN c1.gn = 1 OR c1.Age <> c3.Age THEN 
        CASE WHEN c1.gn > 1 THEN '</li>' ELSE '<ul>' END + '<li>' 
        + CONVERT(VARCHAR(32), c1.Age) ELSE '' END + CHAR(13) + CHAR(10) + CHAR(9) 
        + CHAR(9) + CASE WHEN (c1.gn = 1 OR c1.Age <> c3.Age) THEN '<ul>' ELSE '' END 
        + '<li>' + c1.Name + '</li>' + CASE WHEN c1.Age <> c2.Age OR c1.dr <> c2.dr 
        THEN '</ul>' ELSE '' END
FROM x AS c1 
LEFT OUTER JOIN x AS c2
ON c1.rn = c2.rn - 1
LEFT OUTER JOIN x AS c3
ON c1.rn = c3.rn + 1
ORDER BY c1.Gender DESC, c1.Age;

SELECT @html = @html + '</ul></li></ul></li></ul>';

PRINT @html; -- note you will need to deal with this 
             -- in another way if the string is large

这是它有效的证据:

在此处输入图像描述

于 2012-04-24T15:13:41.317 回答
0
SET ANSI_WARNINGS ON;

DECLARE @Test TABLE
(
    Gender  VARCHAR(10) NOT NULL,
    Age     INT NOT NULL,
    Name    VARCHAR(50) NOT NULL
);

INSERT  @Test (Gender, Age, Name)
SELECT  'Male'  ,30 ,'Bill'
UNION ALL
SELECT  'Female',27 ,'Jenny'
UNION ALL
SELECT  'Female',27 ,'Debby'
UNION ALL
SELECT  'Male'  ,44 ,'Frank';

DECLARE @x XML;
SET     @x = 
(
    SELECT  *
    FROM    @Test t
    FOR XML RAW, ROOT
);
SELECT @x AS [Source];
SELECT @x.query('
    for $g in distinct-values(//root/row/@Gender) (: or for $g in ("Male", "Female") :)
    return
    <ul>
        <li>
            {data($g)}
            <ul>
            {
                for $a in distinct-values(//root/row[@Gender=$g]/@Age)
                return <li>{data($a)}
                <ul>
                {
                    for $n in //root/row
                    where $n/@Gender=$g and $n/@Age = $a
                        return <li>{data($n/@Name)}</li>
                }</ul></li>
            }
            </ul> 
        </li>
    </ul>
') AS Result;

参考:SQL Server XQuery

于 2012-04-24T18:34:56.757 回答