热门将4个查询组合成一个没有具有多个条件的子查询的查询?

时间:2013-10-11 16:15:01

标签: sql-server tsql sql-server-2005

我想要下面的查询:

Select groupId,count (distinct GroupProgramYearParticipantID) as [ChildAddedcurrent] 
from #temp1 Where MonthFlag=0 and ParticipantTypeName='child'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=1 and ParticipantTypeName='child')
group by groupId

Select groupId,count (distinct GroupProgramYearParticipantID) as [CaregiverAddedcurrent] 
from #temp1 Where MonthFlag=0 and ParticipantTypeName='caregiver'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=1 and ParticipantTypeName='caregiver')
group by groupId

Select groupId,count (distinct GroupProgramYearParticipantID) as [ChildAddedprior] 
from #temp1 Where MonthFlag=1 and ParticipantTypeName='child'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=2 and ParticipantTypeName='child')
group by groupId

Select groupId,count (distinct GroupProgramYearParticipantID) as [caregiverAddedPrior] 
from #temp1 Where MonthFlag=1 and ParticipantTypeName='caregiver'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=2 and ParticipantTypeName='caregiver')
group by groupId

更像这样:

select groupID,
count(distinct case when MonthFlag=0 and ParticipantTypeName='child' 
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=1 and ParticipantTypeName='child') then GroupProgramYearParticipantID end) as [ChildAddedcurrent],
count(distinct case when MonthFlag=0 and ParticipantTypeName='caregiver'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=1 and ParticipantTypeName='caregiver') then GroupProgramYearParticipantID end) as [CaregiverAddedcurrent],
count(distinct case when MonthFlag=1 and ParticipantTypeName='child'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=2 and ParticipantTypeName='child')then GroupProgramYearParticipantID end) as [ChildAddedprior],
count(distinct case when MonthFlag=1 and ParticipantTypeName='caregiver'
and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
Where MonthFlag=2 and ParticipantTypeName='caregiver') then GroupProgramYearParticipantID end) as [caregiverAddedPrior]
From #temp1
group by groupID

但是我收到了一个错误:

  

无法对包含聚合或子查询的表达式执行聚合函数。

2 个答案:

答案 0 :(得分:1)

使用UNION(删除重复项)或UNION ALL

SELECT x.groupId, x.Count, x.Type FROM
(    
    Select GroupId,
           Count = count(distinct GroupProgramYearParticipantID),
           Type  = 'ChildAddedcurrent'
    from #temp1 Where MonthFlag=0 and ParticipantTypeName='child'
    and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
    Where MonthFlag=1 and ParticipantTypeName='child')
    group by groupId

    UNION ALL

    Select GroupId,
           Count = count(distinct GroupProgramYearParticipantID),
           Type  = 'CaregiverAddedcurrent'
    from #temp1 Where MonthFlag=0 and ParticipantTypeName='caregiver'
    and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
    Where MonthFlag=1 and ParticipantTypeName='caregiver')
    group by groupId

    UNION ALL

    Select GroupId,
           Count = count(distinct GroupProgramYearParticipantID),
           Type  = 'ChildAddedprior'
    from #temp1 Where MonthFlag=1 and ParticipantTypeName='child'
    and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
    Where MonthFlag=2 and ParticipantTypeName='child')
    group by groupId

    UNION ALL

    Select GroupId,
           Count = count(distinct GroupProgramYearParticipantID),
           Type  = 'caregiverAddedPrior'
    from #temp1 Where MonthFlag=1 and ParticipantTypeName='caregiver'
    and GroupProgramYearParticipantID not in (Select distinct GroupProgramYearParticipantID from #temp1
    Where MonthFlag=2 and ParticipantTypeName='caregiver')
    group by groupId

) X

请注意,我添加了Type列,并将count列的唯一列名称更改为Count。要确定行的来源,我已添加了Type列。 现在,如果需要,您甚至可以按其中一个列进行排序/过滤。

答案 1 :(得分:0)

Aaron对解析错误是正确的。

此外,NOT IN子句的问题意味着你必须检查永远的id来排除一行。当数据很大时,这是一个非常昂贵的操作。

使用公共表表达式CTE与SET运算符是您的关键。请参阅我关于集合运算符的文章。

http://craftydba.com/?p=5617

首先,为每个类别(儿童,护理人员)创建每个月(0,1,2)的CTE。

;
-- Child +0M
with cteChildMonth0
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=0 and ParticipantTypeName='child'
),

-- Child +1M
cteChildMonth1
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=1 and ParticipantTypeName='child'
),

-- Child +2M
cteChildMonth2
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=2 and ParticipantTypeName='child'
),

-- Giver +0M
cteCareGiverMonth0
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=0 and ParticipantTypeName='caregiver'
),

-- Giver +1M
cteCareGiverMonth1
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=1 and ParticipantTypeName='caregiver'
),

-- Giver +2M
cteCareGiverMonth2
as
(
select groupID as group_id, GroupProgramYearParticipantID as participant_id
from #temp1
where MonthFlag=2 and ParticipantTypeName='caregiver'
),

其次,使用之前的6个CTE和SET符号运算符EXCEPT为当前与先前创建CTE。这是在表级完成的,它应该比NOT IN快。对于每一行,为报告创建一个虚拟计数器= 1.

-- Child add current
cteChildAddCurrent
(
select group_id, 'Child Current' as category_txt, 1 as participant_cnt
from cteChildMonth0 except cteChildMonth0 
),

-- Child add prior
cteChildAddPrior
(
select group_id, 'Child Prior' as category_txt, 1 as participant_cnt
from cteChildMonth1 except cteChildMonth2
),

-- Giver add current
cteGiverAddCurrent
(
select group_id, 'Giver Current' as category_txt, 1 as participant_cnt
from cteCareGiverMonth0 except cteCareGiverMonth1
),

-- Giver add prior
cteGiverAddPrior
(
select group_id, 'Giver Prior' as category_txt, 1 as participant_cnt
from cteCareGiverMonth1 except cteCareGiverMonth2
),

第三,将4个类别合并为一个表格。

-- Giver add prior
cteSummaryRpt
(
select * from cteChildAddCurrent
union all
select * from cteChildAddPrior
union all
select * from cteGiverAddPrior
union all
select * from cteGiverAddCurrent
)

最后但并非最不重要的是,按ID,类别文本和参与者计数进行分组。

select group_id, category_txt, sum(participant_cnt) as total
from cteSummaryRpt
group by group_id, category_txt

我将这个解决方案分解成各个部分来解释它,但实际上这是一个大问题。此外,由于您没有提供样本表和/或数据,请检查语法,因为我没有。

祝你好运。