两个"其中"具有一个表的语句在没有子查询的情况下不起作用

时间:2015-02-04 00:19:35

标签: sql sql-server sql-server-2008 tsql where

我有一个包含3列的表格:namelastnamedate

例如:

Name Lastname Date
Ab   Ab       2008-07-01
Ab   Ab       2006-06-23
Kb   Kb       2008-07-01
Kb   Kb       2007-06-03

我需要找到分配到2008-07而不是2006-06的人的姓名。因此,对于此示例,输出将为:

Name Lastname Date
Kb   Kb       2008-07-01
Kb   Kb       2007-06-03

我的代码:

select  Name, Lastname, YEAR(date), MONTH(date) from MyTable
where (YEAR(date) = 2008 AND MONTH(date) = 7) AND (YEAR(date) <> 2006 AND MONTH(date) <> 6)

它不能很好地工作,因为实际上没有任何事情发生(它“阻塞”例如所有月份= 6的名称)。我尝试用UNION语句来做,但没有什么效果。

注意,我需要在不使用子查询的情况下执行此操作。

3 个答案:

答案 0 :(得分:5)

我认为您需要group byhaving子句,因为您正在寻找多行:

select  Name, Lastname
from MyTable
group by Name, LastName
having 
    sum(case when YEAR(date) = 2008 AND MONTH(date) = 7 then 1 else 0 end) > 0 and
    sum(case when YEAR(date) = 2006 AND MONTH(date) = 6 then 1 else 0 end) = 0;

having子句中的每个条件都会计算匹配的行数。 > 0表示至少有一个。 = 0表示没有。这很容易概括为更多条件。

答案 1 :(得分:1)

SELECT
    t.*
FROM (
    SELECT
        Name,
        LastName
    FROM #Temp
    GROUP BY Name, LastName
    HAVING
        SUM(CASE WHEN YEAR([Date]) = 2008 AND MONTH([Date]) = 7 THEN 1 ELSE 0 END) = 1
        AND SUM(CASE WHEN YEAR([Date]) = 2006 AND MONTH([Date]) = 6 THEN 1 ELSE 0 END) = 0
)x
INNER JOIN #Temp t
    ON t.Name = x.Name
    AND t.LastName = x.LastName

<强> RESULT

Name                 LastName             Date
-------------------- -------------------- ----------
Kb                   Kb                   2008-07-01
Kb                   Kb                   2007-06-03

答案 2 :(得分:1)

您可以使用一系列外连接来执行此操作而不使用子查询。

SELECT c1.*
FROM Customers c1
LEFT OUTER JOIN Customers c2 ON
    c1.Name = c2.Name AND c1.LastName = c2.LastName
    AND YEAR(c2.date) = 2006 AND MONTH(c2.date) = 6
LEFT OUTER JOIN Customers c3 ON
    c1.Name = c3.Name AND c1.LastName = c3.LastName
    AND YEAR(c3.date) = 2008 AND MONTH(c3.date) = 7
WHERE 
    c2.date IS NULL
    AND c3.date IS NOT NULL

您断言第一次加入失败,但第二次加入成功。

结果

Kb Kb 7/1/2008 12:00:00 AM 
Kb Kb 6/3/2007 12:00:00 AM