T-SQL: как выбрать строки в качестве элемента XML

У меня есть стол

   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>

Я смог произвести его с помощью TSQL ( Test - это имя моей таблицы)

SELECT
    (SELECT Cost AS 'Cost'FROM Test WHERE SectionName = 'Section1') AS 'Section1Cost',
    (SELECT RenderedValue AS 'Cost'FROM Test WHERE SectionName = 'Section1') AS 'Section1RenderedValue',
    (SELECT Cost AS 'Cost'FROM Test WHERE SectionName = 'Section2') AS 'Section2Cost',
    (SELECT RenderedValue AS 'Cost'FROM Test WHERE SectionName = 'Section2') AS 'Section2RendredValue'
FOR XML Path(''), Root('Root')

Но это безобразно, и я думаю, что это не оптимизировано. Может ли это быть более элегантным или что я имею правильно?

У меня может быть не более 30 строк в этой тестовой таблице

3 ответа

Это дает вам немного отличающийся XML (использующий теги Section), но сценарий 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>

Я думаю, я понял

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')

Привет, вот измененная версия моего предыдущего ответа на основе вашего последнего ответа user3862378

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)

И вот результаты:

<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>
Другие вопросы по тегам