没有子查询,两个 "where" 语句和一个 table 语句不起作用
Two "where" statements with one table doesn't work without subqueries
我有一个包含 3 列的 table:name
、lastname
和 date
。
例如:
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)
效果不佳,因为实际上什么都没有发生(例如 "blocking" 所有名称的月份都为 6)。我尝试用 UNION 语句来做,但没有什么效果。
请注意,我需要在不使用子查询的情况下执行此操作。
我认为您需要一个 group by
和一个 having
子句,因为您要查找多行:
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
表示有 none。这很容易推广到更多条件。
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
结果
Name LastName Date
-------------------- -------------------- ----------
Kb Kb 2008-07-01
Kb Kb 2007-06-03
您可以使用一系列外部联接来实现,而无需子查询。
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
我有一个包含 3 列的 table:name
、lastname
和 date
。
例如:
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)
效果不佳,因为实际上什么都没有发生(例如 "blocking" 所有名称的月份都为 6)。我尝试用 UNION 语句来做,但没有什么效果。
请注意,我需要在不使用子查询的情况下执行此操作。
我认为您需要一个 group by
和一个 having
子句,因为您要查找多行:
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
表示有 none。这很容易推广到更多条件。
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
结果
Name LastName Date
-------------------- -------------------- ----------
Kb Kb 2008-07-01
Kb Kb 2007-06-03
您可以使用一系列外部联接来实现,而无需子查询。
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