Различия по датам из разных выходов - PullRequest
2 голосов
/ 23 февраля 2012

Я пытаюсь выяснить, сколько времени потребуется, пока клиент снова закажет в моем интернет-магазине.

Название списка 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

Теперь было бы здорово получить запрос, который скажет мне, сколько времени потребовалось (at) a.com для повторного заказа. В примере это будет 6 дней. Для c (at) a.com это будет 2 дня. Тогда в конце мне нужно среднее значение всех этих дат, но я должен справиться с этим:)

Большое спасибо за ответы

Ответы [ 4 ]

1 голос
/ 23 февраля 2012

Вот запрос на возврат последнего разрыва в днях для каждого клиента с использованием 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_at - это поле DATE.

Возвращается 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
0 голосов
/ 23 февраля 2012

Возможно, вам лучше всего сделать это с переменными 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

Теперь вы ищетев последний раз между фактическими заказами ... так что у вас есть статус "завершен" или "отменен" по сравнению с просто посещением вашего сайта и попыткой заказа ..

должен создать результирующий курсор что-то вроде

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, чтобы удалить «NULL» записи, которые обозначают ПЕРВЫЙ заказ для человека, и просто оставить те, которые специально имели ВТОРОЙ заказ.Вы даже можете применить значения GROUPING для первой даты, последней даты, а также для общего количества заказов.

0 голосов
/ 23 февраля 2012

РЕДАКТИРОВАТЬ: этот запрос даст вам клиента, последний заказ и предыдущий заказ.Проверьте, отражает ли это то, что вам нужно.Если да, просто укажите дату в столбцах:

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
0 голосов
/ 23 февраля 2012

Чтобы получить результат в соответствии с запросом, попробуйте следующее:

SELECT
    customer_email,
    DATEDIFF(MAX(date), MIN(date))
FROM eshop_flat_sales_order
GROUP BY customer_email
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...