Sql server T-SQL:如何选择行作为XML元素

Sql server T-SQL:如何选择行作为XML元素,sql-server,xml,tsql,for-xml,Sql Server,Xml,Tsql,For Xml,我有一张桌子 Cost RenderedValue SectionName ------------------------------------ 100.00 1000.00 Section1 200.00 2000.00 Section2 300.00 3000.00 Section3 400.00 4000.00 Section4

我有一张桌子

   Cost       RenderedValue    SectionName
   ------------------------------------
  100.00      1000.00          Section1
  200.00      2000.00          Section2
  300.00      3000.00          Section3
  400.00      4000.00          Section4
我想生成以下XML:

<Root>
   <Section1Cost>100.00</Section1Cost>
   <Section1RenderedValue>1000.00</Section1RenderedValue>
   <Section2Cost>200.00</Section2Cost>
   <Section2RendredValue>2000.00</Section2RendredValue>
</Root>
但这是丑陋的,我认为它没有优化。能不能再优雅一点,或者我所有的都是对的


在该测试表中,我最多可以有30行

这会使XML略有不同(使用节标记),但SQL脚本应该更高效:

SELECT
    Test.SectionName AS [@SectionName],
    Test.Cost AS [Cost],
    Test.RenderedValue AS [RenderedValue]

FROM Test
ORDER BY Test.SectionName
FOR XML PATH ('Section'), ROOT('Sections');
这是您提供的示例表的脚本输出:

<Sections><Section SectionName="Section1"><Cost>100.0000</Cost><RenderedValue>1000.0000</RenderedValue></Section><Section SectionName="Section2"><Cost>200.0000</Cost><RenderedValue>2000.0000</RenderedValue></Section><Section SectionName="Section3"><Cost>300.0000</Cost><RenderedValue>3000.0000</RenderedValue></Section><Section SectionName="Section4"><Cost>400.0000</Cost><RenderedValue>4000.0000</RenderedValue></Section></Sections>
100.00001000.00002000.000020000.00003000.000030000.0000400.00004000.0000

这会让您看到略有不同的XML(使用节标记),但SQL脚本应该更高效:

SELECT
    Test.SectionName AS [@SectionName],
    Test.Cost AS [Cost],
    Test.RenderedValue AS [RenderedValue]

FROM Test
ORDER BY Test.SectionName
FOR XML PATH ('Section'), ROOT('Sections');
这是您提供的示例表的脚本输出:

<Sections><Section SectionName="Section1"><Cost>100.0000</Cost><RenderedValue>1000.0000</RenderedValue></Section><Section SectionName="Section2"><Cost>200.0000</Cost><RenderedValue>2000.0000</RenderedValue></Section><Section SectionName="Section3"><Cost>300.0000</Cost><RenderedValue>3000.0000</RenderedValue></Section><Section SectionName="Section4"><Cost>400.0000</Cost><RenderedValue>4000.0000</RenderedValue></Section></Sections>
100.00001000.00002000.000020000.00003000.000030000.0000400.00004000.0000
我想我明白了

EDIT1

我想收回我说过的话,我提到的解决方案并不完全符合我的要求。当记录不存在时,我要打印0。因此,如果修改上述内容,它将不起作用

 select 
 case when t.sectionname = 'section1' then t.cost else 0 end as 'section1cost',
 case when t.sectionname = 'section1' then t.renderedvalue else 0 end as 'section1rendervalue'
 from test t
 for xml path(''),root('root')
我想我明白了

EDIT1

我想收回我说过的话,我提到的解决方案并不完全符合我的要求。当记录不存在时,我要打印0。因此,如果修改上述内容,它将不起作用

 select 
 case when t.sectionname = 'section1' then t.cost else 0 end as 'section1cost',
 case when t.sectionname = 'section1' then t.renderedvalue else 0 end as 'section1rendervalue'
 from test t
 for xml path(''),root('root')

您好,这是我先前答案的修改版本,基于您的最新答案用户3862378

DECLARE @sql varchar(max) = ''
DECLARE @case VARCHAR(MAX) = ''

SELECT  @case += 'case when t.sectionname = '''+SectionName+''' then t.cost  end as '''+SectionName+'Cost'',
 case when t.sectionname = '''+SectionName+''' then t.renderedvalue  end as '''+SectionName+'RenderedValue'','

  FROM <YOUR TABLE NAME>

  SELECT @sql = 'select '+ SUBSTRING(@case,1,LEN(@case)-1) +'from <YOUR TABLE NAME> t
 for xml path(''''),root(''root'')'

 EXECUTE (@sql)
DECLARE@sql varchar(max)=”
声明@case VARCHAR(MAX)=”
当t.sectionname=''+sectionname+''时,选择@case+='case,然后t.cost结束为''+sectionname+'cost',
当t.sectionname='''+sectionname+''时,则t.renderedvalue结束为''+sectionname+'renderedvalue','
从…起
从t中选择@sql='SELECT'+子字符串(@case,1,LEN(@case)-1)+'
对于xml路径(“”),根(“”)
执行(@sql)
结果如下:

<root>
  <Section1Cost>100.00</Section1Cost>
  <Section1RenderedValue>1000.00</Section1RenderedValue>
  <Section2Cost>200.00</Section2Cost>
  <Section2RenderedValue>2000.00</Section2RenderedValue>
  <Section3Cost>300.00</Section3Cost>
  <Section3RenderedValue>3000.00</Section3RenderedValue>
  <Section4Cost>400.00</Section4Cost>
  <Section4RenderedValue>4000.00</Section4RenderedValue>
</root>

100
1000
200
2000
300
3000
400
4000

您好,这是我以前的答案的修改版本,基于您最新的答案用户3862378

DECLARE @sql varchar(max) = ''
DECLARE @case VARCHAR(MAX) = ''

SELECT  @case += 'case when t.sectionname = '''+SectionName+''' then t.cost  end as '''+SectionName+'Cost'',
 case when t.sectionname = '''+SectionName+''' then t.renderedvalue  end as '''+SectionName+'RenderedValue'','

  FROM <YOUR TABLE NAME>

  SELECT @sql = 'select '+ SUBSTRING(@case,1,LEN(@case)-1) +'from <YOUR TABLE NAME> t
 for xml path(''''),root(''root'')'

 EXECUTE (@sql)
DECLARE@sql varchar(max)=”
声明@case VARCHAR(MAX)=”
当t.sectionname=''+sectionname+''时,选择@case+='case,然后t.cost结束为''+sectionname+'cost',
当t.sectionname='''+sectionname+''时,则t.renderedvalue结束为''+sectionname+'renderedvalue','
从…起
从t中选择@sql='SELECT'+子字符串(@case,1,LEN(@case)-1)+'
对于xml路径(“”),根(“”)
执行(@sql)
结果如下:

<root>
  <Section1Cost>100.00</Section1Cost>
  <Section1RenderedValue>1000.00</Section1RenderedValue>
  <Section2Cost>200.00</Section2Cost>
  <Section2RenderedValue>2000.00</Section2RenderedValue>
  <Section3Cost>300.00</Section3Cost>
  <Section3RenderedValue>3000.00</Section3RenderedValue>
  <Section4Cost>400.00</Section4Cost>
  <Section4RenderedValue>4000.00</Section4RenderedValue>
</root>

100
1000
200
2000
300
3000
400
4000

不,这不是我想要的。我不能改变xml的结构。不,这不是我想要的。我无法更改xml的结构。但这不会像section1、section2等中那样为您动态命名xml标记,或者这是不需要的吗?不,xml元素是固定的,元素名称基于SectionName谢谢您的评论。我想我有你需要的确切答案。请参阅我的最新答案。但这不会像section1、section2等中那样为您动态命名XML标记,或者这是不需要的?不,XML元素是固定的,元素名称基于SectionName谢谢您的评论。我想我有你需要的确切答案。请参阅我的最新答案。这应该动态创建每个元素,其名称基于SectionName列中的值。这应该动态创建每个元素,其名称基于SectionName列中的值。请注意,所有回答SO的专业人士都渴望获得声誉积分。如果你也能看看你以前的问题,那就太好了。谢谢!请注意,所有回答SO的专业人士都渴望获得声誉积分。如果你也能看看你以前的问题,那就太好了。谢谢!