SQL输出问题

时间:2011-02-18 21:43:51

标签: sql sql-server sql-server-2008

被修改

我遇到了一个错误,我知道发生了什么,但我看不出是什么导致了它。下面是我正在使用的sql代码。基本上我得到了我想要的一般结果,但是我没有准确地给出查询正确的'where'子句。

如果这有任何帮助。伯爵计数如下:

Total       Tier
1           High
2           Low

注册表中有4条记录。 3表示活动,1表示不活跃。只显示2条记录。 1表示高,1表示低。总计中的第二个低记录在2010年12月30日被标记为“非活动”,并在2011年1月12日再次报废,因此不应出现在结果中。我将最初的'< ='更改为'=',结果保持不变。

我需要从日期之前将“active_status”更改为0的Enrollments_Status_Change中排除任何记录。

SELECT COUNT(dbo.Enrollments.Customer_ID) AS Total,
       dbo.Phone_Tier.Tier 
  FROM dbo.Phone_Tier as p
  JOIN dbo.Enrollments as eON p.Phone_Model = e.Phone_Model
       WHERE (e.Customer_ID NOT IN
               (Select Customer_ID
                From dbo.Enrollment_Status_Change as Status
                Where (Change_Date >'12/31/2010')))
 GROUP BY dbo.Phone_Tier.Tier

感谢您的任何帮助,我为任何困惑道歉。这是我第一次来这里,我正试图在飞行中纠正我的礼节。

2 个答案:

答案 0 :(得分:2)

如果您不想要该表dbo.Enrollment_Status_Change中的任何字段,并且您似乎没有以任何方式使用它 - 为什么甚至将它包含在JOIN中?把它留下来吧。

Plus:开始使用表别名。如果在每个JOIN条件和WHERE子句中使用完整的表名,则很难阅读。

您的代码应为:

SELECT 
    COUNT(e.Customer_ID) AS Total, p.Tier 
FROM 
    dbo.Phone_Tier p
INNER JOIN 
    dbo.Enrollments e ON p.Phone_Model = e.Phone_Model 
WHERE 
    e.Active_Status = 1 
    AND EXISTS (SELECT DISTINCT Customer_ID 
                FROM dbo.Enrollment_Status_Change AS Status 
                WHERE (Change_Date <= '12/31/2010')) 
GROUP BY 
    p.Tier

另外:很可能,你的EXISTS检查是错误的 - 因为你没有发布你的桌面结构,我只能猜测 - 但我的猜测是:

    AND EXISTS (SELECT * FROM dbo.Enrollment_Status_Change 
                WHERE Change_Date <= '12/31/2010' AND CustomerID = e.CustomerID) 

检查dbo.Enrollment_Status_Change中由e.CustomerID定义的客户是否存在任何条目,并在该截止日期前Change_Date。正确?

答案 1 :(得分:0)

假设你想:

  • 排除自2011年初以来最新enrollment_status_change记录的所有客户

  • 包括最新enrollment_status_change记录早于2010年底的所有客户(为什么还要将EXISTS条款放入?)

然后这应该这样做:

SELECT COUNT(e.Customer_ID) AS Total,
       p.Tier 
  FROM dbo.Phone_Tier p
  JOIN dbo.Enrollments e ON p.Phone_Model = e.Phone_Model
 WHERE dbo.Enrollments.Active_Status = 1
   AND e.Customer_ID NOT IN (
    SELECT Customer_ID
              FROM dbo.Enrollment_Status_Change status
             WHERE (Change_Date >= '2011-01-01')
   )
 GROUP BY p.Tier

基本上,代码的问题在于加入一对多表会增加行数。如果你想排除 all 在另一个表中有匹配行的记录,那就没问题了 - 你可以使用LEFT JOIN然后设置一个WHERE子句,如Customer_ID IS NULL。

但是因为要排除enrollment_status_change表的子集,所以必须使用子查询。

根据给出的示例,您的意图并不明确,但是如果您想排除2011年以前注册者_status_change,但包括自2011年以来状态变化的人,您只需将日期比较器换成&lt;。

这有什么帮助吗?