2

我得到了这个包含 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>'
4

2 回答 2

3
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')
于 2012-01-09T07:13:47.887 回答
2

您可以使用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>
于 2012-01-09T07:00:43.070 回答