TSQL получение количества записей и записей в одном запросе - PullRequest
2 голосов
/ 09 января 2012

Я получил эту таблицу задач, в которой есть элементы TODO. Мы извлекаем элементы задач и количество завершенных задач, ожидающих выполнения, используя отдельный запрос в одной хранимой процедуре, даже если он запрашивает из одной таблицы. Вот запрос,

select
TaskName 'Task/TaskName',
CASE IsDone WHEN '1' THEN 'True' ELSE 'False' END 'Task/IsDone',
(
 SELECT COUNT(*) FROM Tasks WHERE IsDone = '1'
) 'CompletedCount'
FROM Tasks FOR XML PATH('Tasks')

здесь вывод

'<Tasks>
    <Task>
        <TaskName>Write a email to Mayor<TaskName>
        <IsDone>True</IsDone>
        <CompletedCount>2<CompletedCount>
    </Task>
</Tasks>'

CompletedCount присутствует в каждой задаче, которая является ненужной, и есть ли она в любом случае, я тоже могу запросить счет без явной записи этого SELECT COUNT(*) FROM Tasks WHERE IsDone = '1'

Как получить вывод, как показано ниже

'<Tasks>
    <CompletedCount>2<CompletedCount>
    <Task>
        <TaskName>Write a email to Mayor<TaskName>
        <IsDone>True</IsDone>
    </Task>
    <Task>
        <TaskName>Organize Campaign for website<TaskName>
        <IsDone>False</IsDone>
    </Task>
</Tasks>'

Ответы [ 2 ]

3 голосов
/ 09 января 2012
select (
          select count(*)
          from Tasks
          where IsDone = 1
          for xml path('CompletedCount'), type
       ),
       (
          select TaskName,
                 case IsDone 
                   when 1 then 'True' 
                   else 'False' 
                 end as IsDone
          from Tasks
          for xml path('Task'), type
       )
for xml path('Tasks')

Обновление:
Вы можете сделать это с помощью одного выбора, если вы сначала создадите свой список задач, а затем запросите XML для полного подсчета. Я сомневаюсь, что это будет быстрее, чем использование двух операторов select.

;with C(Tasks) as
(
  select TaskName,
         case IsDone 
           when 1 then 'True' 
           else 'False' 
         end as IsDone
  from Tasks
  for xml path('Task'), type
)
select C.Tasks.value('count(/Task[IsDone = "True"])', 'int') as CompletedCount,
       C.Tasks
from C
for xml path('Tasks')
2 голосов
/ 09 января 2012

Вы можете использовать type для вычисления части XML в подзапросе:

declare @todo table (TaskName varchar(50), IsDone bit)
insert @todo values ('Buy milk',1)
insert @todo values ('Send thank you note',1)

select  sum(case when isdone = 1 then 1 end) as 'CompletedCount'
,       (
        select  TaskName 'TaskName'
        ,       case when isdone = 1 then 'True' else 'False' end 'IsDone'
        from    @todo
        for xml path('Task'), type
        ) as 'TaskList'
from    @todo
for xml path('Tasks')

Это печатает:

<Tasks>
    <CompletedCount>2</CompletedCount>
    <TaskList>
        <Task>
            <TaskName>Buy milk</TaskName>
            <IsDone>True</IsDone>
        </Task>
        <Task>
            <TaskName>Send thank you note</TaskName>
            <IsDone>True</IsDone>
        </Task>
    </TaskList>
</Tasks>
...