[英]How to reuse subquery in T-SQL View
我正在尝试优化一个SQL视图。 这里的关系是一对多的,一个项目有很多任务:
create view [schema].[vName]
select p.ProjectId as 'ProjectId'
-- ...
-- excluded some selected columns and subqueries where this comment is
-- ...
, (select count(t.TaskId)
from Task t with (nolock)
where t.PrimarySearchEntityId = p.ProjectId and t.IsDeleted = 0) as 'Total_Tasks'
, (select count(t.TaskId)
from Task t with (nolock)
where t.PrimarySearchEntityId = p.ProjectId and isnull(t.taskowner, 'Unassigned') <> 'Unassigned' and t.IsDeleted = 0) as 'Assigned_Tasks'
, (select count(t.TaskId)
from Task t with (nolock)
where t.PrimarySearchEntityId = p.ProjectId and t.TaskStatusId in (400, 500) and
t.IsDeleted = 0) as 'Completed_Tasks'
, (select count(t.TaskId)
from Task t with (nolock)
where t.PrimarySearchEntityId = p.ProjectId and t.TaskStatusId not in (400, 500) and
t.IsDeleted = 0) as 'Remaining_Tasks'
, (select count(t.TaskId)
from Task t with (nolock)
where t.PrimarySearchEntityId = p.ProjectId and t.DueDate < getutcdate() and t.TaskStatusId not in (400, 500) and t.IsDeleted = 0) as 'Late_Tasks'
, (select (case when count(t.taskid) > 0 then 'Overdue' else 'all' end)
from Task t with (nolock)
from project p with (nolock)
-- there are some additional joined tables here ...
如您所见,我一次又一次地选择同一子查询的子集计数,查询本质上是:
select * from Task where IsDeleted = 0 and Task.PrimarySearchEntityId = p.ProjectId
我如何才能重新使用此结果集,然后从那里进行过滤? 我可以使用cte,但是问题是我需要了解Advanced的ProjectId,所以这行不通。 我不想使用联接,因为我希望此视图中的每个记录成为该项目的唯一记录。 这里有什么建议吗? 我可以将这些Tasks
分组或重用结果集的某种方式?
您可以使用相关的子查询来计算所有总数:
create view [schema].[vName]
as
select p.ProjectId as 'ProjectId',
tsk.Total_Tasks, tsk.Assigned_Tasks, tsk.Completed_Tasks, tsk.Remaining_Tasks,
...
from project p with (nolock)
cross apply (
select count(*) as [Total_Tasks],
count(case when t.taskowner != 'Unassigned' then 1 end) as [Assigned_Tasks],
count(case when t.TaskStatusId in (400, 500) then 1 end) as [Completed_Tasks],
count(case when t.TaskStatusId not in (400, 500) then 1 end) as [Remaining_Tasks],
-- Et cetera, ad infinitum...
from dbo.Task t
where t.PrimarySearchEntityId = p.ProjectId and t.IsDeleted = 0
) tsk
-- there are some additional joined tables here ...
由于只有一组分组,因此查询可以简化为:
select p.ProjectId,
count(t.TaskId) as Total_Tasks,
count(case when t.taskowner != 'Unassigned' then 1 end) as Assigned_Tasks,
count(case when t.TaskStatusId in (400, 500) then 1 end) as Completed_Tasks,
count(case when t.TaskStatusId not in (400, 500) then 1 end) as Remaining_Tasks,
count(case when t.DueDate < getutcdate() and t.TaskStatusId not in (400, 500) then 1 end) as Late_Tasks
from project p with (nolock)
left join dbo.Task t on t.PrimarySearchEntityId = p.ProjectId and t.IsDeleted = 0
group by p.ProjectId
如果您要分组的表有多个,那么您就必须按照其他答案去一个子查询,尽管没有理由对左联接使用交叉应用。
select p.ProjectId, Total_Tasks, Assigned_Tasks, Completed_Tasks, Remaining_Tasks, Late_Tasks
from project p
left join (
select
PrimarySearchEntityId,
count(TaskId) as Total_Tasks,
count(case when taskowner != 'Unassigned' then 1 end) as Assigned_Tasks,
count(case when skStatusId in (400, 500) then 1 end) as Completed_Tasks,
count(case when t.TaskStatusId not in (400, 500) then 1 end) as Remaining_Tasks,
count(case when DueDate < getutcdate() and TaskStatusId not in (400, 500) then 1 end) as Late_Tasks
from dbo.Task
where IsDeleted=0
group by PrimarySearchEntityId
) t on t.PrimarySearchEntityId = p.ProjectId
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.