在2001年至2012年期间订购过多次的客户。在此列表中,我们需要2012年之后未订购的客户群

时间:2015-11-26 13:46:48

标签: sql-server

我有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

2 个答案:

答案 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
;