【发布时间】:2012-12-02 16:59:20
【问题描述】:
我有一个名为 Orders 的表,其中包含以下字段: 客户 ID、订单日期
例如
1, 01/01/2011
2, 02/02/2011
1, 01/07/2012
我正在尝试找出一种方法来查询此表,以了解客户是否在 2011 年订购了并且在 2012 年没有订购任何东西,并返回不同的客户 ID ...
【问题讨论】:
我有一个名为 Orders 的表,其中包含以下字段: 客户 ID、订单日期
例如
1, 01/01/2011
2, 02/02/2011
1, 01/07/2012
我正在尝试找出一种方法来查询此表,以了解客户是否在 2011 年订购了并且在 2012 年没有订购任何东西,并返回不同的客户 ID ...
【问题讨论】:
比较这两种方法以确定哪些 OrderDates 来自 2012 年:
Year(OrderDate) = 2012OrderDate >= #2012-01-01# AND OrderDate < #2013-01-01#第一种方法写起来简单易懂。但是,它需要数据库引擎访问您的Orders 表中的每一行并使用该Year() 函数来查看该行是否符合您的标准。当表很大时,如果它包含许多 OrderDates 超出目标范围的行,这可能会花费很多时间。最重要的是,由于该函数会强制数据库引擎检查每一行,因此您的查询无法利用索引来加速数据检索。
第二种方法虽然更冗长,但允许 db 引擎仅检查那些满足您的标准的行。使用OrderDate 上的索引,它可以轻松地比第一种方法快一个数量级。
如果您的桌子足够小和/或您不关心性能,那么这对您来说不是问题。不过,我还是建议你试试这个版本...
SELECT DISTINCT o2011.CustomerID
FROM
Orders AS o2011
LEFT JOIN
(
SELECT DISTINCT CustomerID
FROM Orders
WHERE
OrderDate >= #2012-01-01#
AND OrderDate < #2013-01-01#
) AS sub2012
ON o2011.CustomerID = sub2012.CustomerID
WHERE
o2011.OrderDate >= #2011-01-01#
AND o2011.OrderDate < #2012-01-01#
AND sub2012.CustomerID Is Null;
【讨论】:
你可以试试这个:
select distinct CustomerID
from Orders
where year(OrderDate) = 2011
and CustomerID not in (
select distinct CustomerID
from Orders
where year(OrderDate) = 2012
)
【讨论】:
LEFT JOIN(带有is null 条件)是否会表现得更好,但结果会是一样的。如果你在OrderDate 上有一个索引,那么使用日期范围肯定会比YEAR 函数更好。但你自己试试看。