TSQL:对外部连接表的计数产生不正确的结果

TSQL: Count on outer joined tables is producing incorrect results

正在生成关于 SQL Server 2008 的报告。我加入了一个 table 和另外五个使用 LEFT OUTER JOIN 的报告。当我 运行 与其他 table 进行计数时,我得到了不正确的数据。我知道为什么,但我不确定如何解决它。

查询正在跟踪学校的招生候选人。当他们在流程中移动时,他们会在流程的每个主要阶段进行标记。我需要的是计算在特定时期(年和月)有多少人通过了特定阶段。大多数情况下它有效。但是,如果候选人通过了该期间的任何阶段,则该候选人在之前的阶段也会获得 "counted",即使它们发生在查询期间之前。一个很好的例子是 AD_35,其中某个特定的学术课程应该有一个人,但输出显示 2。当我仅查询 AD_35 table 时,我得到了正确的信息。所以我知道问题出在外部连接上,但我不确定如何解决这个问题(在生成我的命名输出的子查询中尝试了各种条件)。对某人来说应该是一个简单的......提前致谢,代码如下。 :Year 和 :Month 用于用户输入,将填充数值(例如 2015 1)

顺波

SELECT DISTINCT 
   ad_candidacy.prog_cde,   
   ad_candidacy.stageyr,   
   ad_candidacy.stagemo,   
   Count (case when (ad_02.stageyr in (:Year, :Year -1, :Year-2) and ad_02.stagemo <= :month) then 1 else null end) as Inquiry,   
   Count (case when (ad_05.stageyr in (:Year, :Year -1, :Year-2) and ad_05.stagemo <= :month) then 1 else null end) as Applied,   
   Count (case when (ad_35.stageyr in (:Year, :Year -1, :Year-2) and ad_35.stagemo <= :month and ad_35.id_num = ad_candidacy.id_num and ad_35.stageyr = ad_candidacy.stageyr and ad_35.stagemo=ad_candidacy.stagemo) then 1 else null end) as Accepted,   
   Count (case when (ad_50.stageyr in (:Year, :Year -1, :Year-2) and ad_50.stagemo <= :month) then 1 else null end) as Matriculated,   
   Count (case when (ad_enroll.stageyr in (:Year, :Year -1, :Year-2) and ad_enroll.stagemo <= :month) then 1 else null end) as Enrolled,   
   ad_candidacy.stagemo_long  
FROM 
   ad_candidacy 
LEFT OUTER JOIN 
   ad_02 ON ad_candidacy.id_num = ad_02.id_num 
LEFT OUTER JOIN 
   ad_05 ON ad_candidacy.id_num = ad_05.id_num 
LEFT OUTER JOIN 
   ad_35 ON ad_candidacy.id_num = ad_35.id_num 
LEFT OUTER JOIN 
   ad_enroll ON ad_candidacy.id_num = ad_enroll.id_num 
LEFT OUTER JOIN 
   ad_50 ON ad_candidacy.id_num = ad_50.id_num  
WHERE 
   (ad_candidacy.stageyr in (:Year, :Year -1, :Year-2) ) 
   AND ( ad_candidacy.stagemo <= :Month )   
GROUP BY 
   ad_candidacy.prog_cde,   
   ad_candidacy.stageyr,   
   ad_candidacy.stagemo,   
   ad_candidacy.stagemo_long  
ORDER BY 
   ad_candidacy.stageyr ASC  

加入多个 table 需要考虑加入条件。第二个 table 有可能同一行有多行。为确保最终得到重复项,您可以在加入第一个 table.

之前在子查询中搜索第二个 table
SELECT a.Name, 
       b.Total
FROM table1 as a
LEFT OUTER JOIN ( SELECT table1Id, Total = COUNT(b.some_measure) from table2 group by table1Id)as b ON a.table1Id = b.table1Id

Ako 的回复为我指明了正确的方向。我正在使用子查询,但他的示例导致了正确的输出。以下是代码的工作版本。谢谢!

SELECT DISTINCT 
   ad_candidacy.prog_cde,   
   ad_candidacy.stageyr,   
   ad_candidacy.stagemo, 
   ad_candidacy.StageMo_Long,
   COUNT (case when (Inquiry IS NOT NULL) then 1 else null end) as Inquiry,
   COUNT (case when (Applied IS NOT NULL) then 1 else null end) as Applied,
   count (case when (Accepted is not null) then 1 else null end) as Accepted,
   COUNT (case when (Matriculated IS NOT NULL) then 1 else null end) as Matriculated,
   count (case when (Enrolled is not null) then 1 else null end) as Enrolled
FROM 
   ad_candidacy
LEFT OUTER JOIN
 (select id_num, Inquiry = COUNT (id_num) from ad_02 where stageyr in (:year, :year-1, :year-2) and StageMo <= :month group by id_num) as ad_02 on ad_candidacy.id_num = ad_02.id_num     
LEFT OUTER JOIN
 (select id_num, Accepted = COUNT (id_num) from ad_35 where stageyr in (:year, :year-1, :year-2) and StageMo <= :month group by id_num) as ad_35 on ad_candidacy.id_num = ad_35.id_num    
LEFT OUTER JOIN
 (select id_num, Applied = COUNT (id_num) from ad_05 where stageyr in (:year, :year-1, :year-2) and StageMo <= :month group by id_num) as ad_05 on ad_candidacy.id_num = ad_05.id_num    
LEFT OUTER JOIN
 (select id_num, Matriculated = COUNT (id_num) from ad_50 where stageyr in (:year, :year-1, :year-2) and StageMo <= :month group by id_num) as ad_50 on ad_candidacy.id_num = ad_50.id_num   
LEFT OUTER JOIN
 (select id_num, Enrolled = COUNT (id_num) from ad_enroll where stageyr in (:year, :year-1, :year-2) and StageMo <= :month group by id_num) as ad_enroll on ad_candidacy.id_num = ad_enroll.id_num  
WHERE 
   (ad_candidacy.stageyr in (:year, :year-1, :year-2) ) 
   AND ( ad_candidacy.stagemo <= :month )   
GROUP BY 
   ad_candidacy.prog_cde,   
   ad_candidacy.stageyr,   
   ad_candidacy.stagemo,   
   ad_candidacy.stagemo_long