我有Orderdetails表。在此表中,我的客户在2001年至2012年期间订购过多次。
在此列表中,我需要在2012年之后未订购的客户群。
我写了这个查询:
select distinct CustomerEmail, orderdate
from orderdetails
where OrderDate between Convert(varchar(50),'01/01/2001',101)
and Convert(varchar(50),'12/31/2012',101)
and customeremail not in (
select distinct CustomerEmail
from orderdetails
where OrderDate between Convert(varchar(50),'01/01/2012',101)
and Convert(varchar(50),'10/31/2014',101)
)
and TransactionId is null
答案 0 :(得分:0)
以下内容应该可以满足您的需求。显然,用您的客户标识符替换“客户”。
select distinct CustomerEmail, orderdate from orderdetails
where customer NOT IN (
select customer from orderdetails where orderdate between '20120101' and '20140101'
这是基于您使用sql server的假设而完成的,它确实说明了标签中的3个RDBMS系统。
提示强>
尝试并避免在where子句中转换/转换日期,它会对性能产生严重影响
答案 1 :(得分:0)
您是否考虑过使用HAVING(MSDN)条款?它允许您在聚合列上执行WHERE like函数。
此示例返回2012年至2014年期间最近订单年度未落入的所有商家。
我在这里使用过CTE,因为我没有相同的表格可供我使用。但是,查询底部的SELECT语句的原理才是真正重要的:
/* This query should return from OrderDetail
* customers who have not ordered between 2012
* and 2014.
* Only customer A no orders in this window.
*/
WITH OrderDetail AS
(
/* Sample order detail table.
* Customer A has orders in 2001 & 2011.
* Customer B has orders in 2013, only.
*/
SELECT
r.CustomerId,
r.OrderDate,
r.OrderValue
FROM
(
VALUES
('A', '2001-01-01', 10.10),
('A', '2001-02-03', 25.17),
('A', '2011-11-25', 10.22),
('B', '2013-01-07', 37.50)
) AS r(CustomerId, OrderDate, OrderValue)
)
-- ********************************************************
-- You can ignore the common table expresssion (CTE) above.
-- I've only included it so you can see/change the sample
-- data. This should make testing easier.
-- ********************************************************
SELECT
CustomerId,
MIN(OrderDate) AS FirstOrderPlaced,
MAX(OrderDate) AS LastOrderPlaced,
COUNT(*) AS OrdersPlaced,
SUM(OrderValue) AS LifetimeOrderValue
FROM
OrderDetail
GROUP BY
CustomerId
HAVING
YEAR(MAX(OrderDate)) NOT BETWEEN 2012 AND 2014
;