日期与不同产出的差异

时间:2012-02-23 13:01:20

标签: mysql sql

我试着找出客户在我的电子商店再次订购需要多长时间。

列表名称eshop_flat_sales_order

customer_email created_at status
------------------------------------
a(at)a.com     12.1.10    complete
b(at)a.com     14.2.10    cancelled
c(at)a.com     16.1.10    complete
a(at)a.com     18.1.10    complete
c(at)a.com     18.1.10    complete
b(at)a.com     20.1.10    complete

使用查询

SELECT *
FROM eshop_flat_sales_order
ORDER BY customer_email

我会收到订单中包含日期的所有电子邮件。像这样:

customer_email created_at status
------------------------------------
a(at)a.com     12.1.10    complete
a(at)a.com     18.1.10    complete
b(at)a.com     14.2.10    cancelled
b(at)a.com     20.1.10    complete
c(at)a.com     16.1.10    complete
c(at)a.com     18.1.10    complete

现在很高兴得到一个查询,告诉我a.com再次订购需要多长时间。在这个例子中它将是6天。对于c(at)a.com,这将是2天。然后最后我需要所有这些日期的平均值,但我应该管理:)

非常感谢你的回答

4 个答案:

答案 0 :(得分:1)

这是一个查询,使用JOIN:

返回每个客户的最新差距(以天为单位)
SELECT e1.customer_email, DATEDIFF(e1.created_at, e2.created_at) AS gap
FROM eshop_flat_sales_order e1
LEFT JOIN eshop_flat_sales_order e2
  ON e2.customer_email = e1.customer_email
  AND e2.created_at < e1.created_at
LEFT JOIN eshop_flat_sales_order e3
  ON e3.customer_email = e1.customer_email
  AND e3.created_at < e2.created_at
WHERE e3.customer_email IS NULL
ORDER BY e1.customer_email

此查询假定created_atDATE字段。

对于NULL,客户只有一个订单会返回gap。如果您不想仅为一个订单的客户返回结果,请将第一次加入从LEFT JOIN更改为JOIN

这是另一个仅考虑complete订单的版本:

SELECT e1.customer_email, DATEDIFF(e1.created_at, e2.created_at) AS gap
FROM eshop_flat_sales_order e1
LEFT JOIN eshop_flat_sales_order e2
  ON e2.customer_email = e1.customer_email
  AND e2.created_at < e1.created_at
  AND e2.status = 'complete'
LEFT JOIN eshop_flat_sales_order e3
  ON e3.customer_email = e1.customer_email
  AND e3.created_at < e2.created_at
  AND e3.status = 'complete'
WHERE e1.status = 'complete'
  AND e3.customer_email IS NULL
ORDER BY e1.customer_email

这将显示所有客户的所有相应订单之间的所有差距:

SELECT e1.customer_email, DATEDIFF(e1.created_at, e2.created_at) AS gap
FROM eshop_flat_sales_order e1
JOIN eshop_flat_sales_order e2
  ON e2.customer_email = e1.customer_email
  AND e2.created_at < e1.created_at
  AND e2.status = 'complete'
LEFT JOIN eshop_flat_sales_order e3
  ON e3.customer_email = e1.customer_email
  AND e3.created_at < e1.created_at
  AND e3.created_at > e2.created_at
  AND e3.status = 'complete'
WHERE e1.status = 'complete'
  AND e3.customer_email IS NULL
ORDER BY e1.customer_email ASC, e1.created_at DESC

这将显示每位客户的平均差距:

SELECT e1.customer_email, AVG(DATEDIFF(e1.created_at, e2.created_at)) AS gap
FROM eshop_flat_sales_order e1
JOIN eshop_flat_sales_order e2
  ON e2.customer_email = e1.customer_email
  AND e2.created_at < e1.created_at
  AND e2.status = 'complete'
LEFT JOIN eshop_flat_sales_order e3
  ON e3.customer_email = e1.customer_email
  AND e3.created_at < e1.created_at
  AND e3.created_at > e2.created_at
  AND e3.status = 'complete'
WHERE e1.status = 'complete'
  AND e3.customer_email IS NULL
GROUP BY e1.customer_email

答案 1 :(得分:0)

要按要求获得结果,请尝试以下操作:

SELECT
    customer_email,
    DATEDIFF(MAX(date), MIN(date))
FROM eshop_flat_sales_order
GROUP BY customer_email

答案 2 :(得分:0)

编辑: 此查询将为您提供客户,最后一个订单和之前的订单。 检查它是否反映了您的需求。如果是,只需对列进行约会:

with last_order as
(
    select customer_email, max(created_at) as max_order, max (ID) as max_id
    from eshop_flat_sales_order 
    where status='complete'
    group by customer_email
)
Select customer_email, MAX_ORDER, 
(select top 1 created_at 
 from eshop_flat_sales_order o 
 where customer_email=lo.customer_email and ID!= lo.max_id and status='complete'
 order by created_at desc) as PREVIOUS_ORDER
from last_order LO  

每个客户总是有2条记录吗?如果是,请尝试:

select customer_email, datediff(day, min(created_at),max(created_at))
from eshop_flat_sales_order
where status='complete'
group by customer_email
having count(*)=2

答案 3 :(得分:0)

你可能最好用SQL变量来做...因此你可以随时使用最后一个人及其相应的活动日期......

SELECT 
      PreSort.customer_email, 
      @lastDate as LastOrderDate,
      PreSort.Created_At,
      if( @lastCust = PreSort.customer_email, 
         datediff( @lastDate, PreSort.Created_At ), null ) as DaysDiff,
      @lastDate := PreSort.Created_At as PreserveDate,
      @lastCust := PreSort.customer_email as PreserveCustomer
   FROM 
      ( select efso.customer_email,
               efso.created_at 
            from eshop_flat_sales_order AS efso
            where efso.status = 'complete'
            order by efso.customer_email,
                     efso.created_at ) PreSort,
      (SELECT @lastCust := '', @lastDate := null ) AS SqlVars

现在,您正在寻找最后一次BETWEEN ACTUAL Orders ...所以您的状态为“完成”或“取消”,只需访问您的网站并尝试订购..

应创建类似

的结果光标
customer_email LastOrderDate created_at DaysDiff   PreserveDate PreserveCustomer
-------------- ------------- ---------- ---------- ------------ ----------------
a(at)a.com     NULL          12.1.10    NULL       12.1.10      a(at)a.com
a(at)a.com     12.1.10       18.1.10    6          18.1.10      a(at)a.com
b(at)a.com     NULL          20.1.10    NULL       20.1.10      b(at)a.com
c(at)a.com     NULL          16.1.10    NULL       16.1.10      c(at)a.com
c(at)a.com     16.1.10       18.1.10    2          18.1.10      c(at)a.com

现在,如果你想要平均值,你可以滚动这些记录并从DaysDiff获得平均值。但是,您可能希望应用WHERE来删除指示一个人的FIRST顺序的“NULL”条目,并将那些特别是HAD的条目留下。您甚至可以为第一个日期,最后日期,总订单应用GROUPING值。