SQL未返回预期记录

时间:2014-12-30 17:27:59

标签: tsql sql-server-2008-r2

这对我来说是一个简单的错误。我有一张有许可证的桌子(申请人有一张许可证) - 上赛季约有600人到期,而前一季约有900人。我需要生成一个独特申请人的邮件列表,这些申请人在过去两个季节都有许可证。

SELECT COUNT(*) FROM Backyard_Burn WHERE YEAR(Expiration_Date)= 2014

SELECT COUNT(*) FROM Backyard_Burn WHERE YEAR(Expiration_Date)= 2013

SELECT COUNT(*) FROM Backyard_Burn WHERE YEAR(Expiration_Date)= 2013
AND Applicant_Mail_ID NOT IN(
  SELECT Applicant_Mail_ID 
  FROM Backyard_Burn 
  WHERE YEAR(Expiration_Date)= 2014)

返回:618,923和0

为什么0而不是923 - 618附近的数字,假设大多数是重复申请者?

2 个答案:

答案 0 :(得分:4)

NOT IN可能很危险。问题可能是由于Applicant_Mail_id采用NULL值而导致的。您可以通过以下方式轻松解决此问题:

SELECT COUNT(*)
FROM Backyard_Burn
WHERE YEAR(Expiration_Date) = 2013 AND
      Applicant_Mail_ID NOT IN (SELECT Applicant_Mail_ID 
                                FROM Backyard_Burn 
                                WHERE YEAR(Expiration_Date) = 2014 AND Applicant_Mail_ID IS NOT NULL
                               );

如果这些值中的任何一个是NULL,那么NOT IN只能返回FALSE或NULL - 条件永远不允许记录通过。

出于这个原因,我认为最好使用NOT EXSTS,当某些值可能是NULL时,SELECT COUNT(*) FROM Backyard_Burn bb WHERE YEAR(Expiration_Date) = 2013 AND NOT EXISTS (SELECT 1 FROM Backyard_Burn bb2 WHERE YEAR(bb2.Expiration_Date) = 2014 AND bb2.Applicant_Mail_ID = bb.Applicant_Mail_ID ); 具有您期望的语义:

group by

编辑:

顺便说一句,制定此方法的另一种方法是使用havingselect Applicant_Mail_ID from Backyard_Burn group by Applicant_Mail_ID having sum(case when year(Expiration_Date) = 2013 then 1 else 0 end) > 0 and sum(case when year(Expiration_Date) = 2014 then 1 else 0 end) > 0;

NULL

这可以避免{{1}}的问题,并且可以轻松添加新条件,例如的申请人在2012年有任何记录。

答案 1 :(得分:0)

  1. 您需要过去两个季节的申请人 - 您需要使用大于运营商
  2. 最好检查完整日期,而不是使用year
  3. 获取年份值
  4. 获取可以使用distinct
  5. 的独特申请人

    结果是:

     select count(distinct Applicant_Mail_ID)
     from Backyard_Burn
     where Expiration_Date >= '20130101';