Новая запись после года отсутствия записей

#sql #ms-access

#sql #ms-access

Вопрос:

Я хочу найти возвращающихся клиентов, которые разместили заказ через год без заказов. Я справился с приведенным ниже, но мне сложно добавить разрыв в год. Что-то вроде «и количество заказов между датами = 0″… любые идеи будут оценены, я, похоже, вообще не могу понять требуемый синтаксис.

 SELECT
  Min(Orders.[Order Date]) AS [MinOfOrder Date],
  Max(Orders.[Order Date]) AS [MaxOfOrder Date],
  Orders.CustomerID
FROM
  Customers
  INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
GROUP BY
  Orders.CustomerID
HAVING
  (
    ((Min(Orders.[Order Date])) < Date() -365)
    AND ((Max(Orders.[Order Date])) > Date() -30)
  );
  

Комментарии:

1. Можете ли вы поделиться структурой своей Orders таблицы?

Ответ №1:

Вы можете использовать exists и not exists для получения первого заказа после годичного перерыва:

 select o.*
from orders as o
where exists (select 1
              from orders as o2
              where o2.customerid = o.customerid and
                    o2.orderdate < dateadd("yyyy", o.orderdate, -1)
             ) and
      not exists (select 1
                  from orders as o2
                  where o2.customerid = o.customerid and
                        o2.orderdate >= dateadd("yyyy", o.orderdate, -1) and
                        o2.orderdate < o.orderdate
                 );
  

Вы можете присоединиться к информации о клиентах, если вам это нужно.

Комментарии:

1. Красота, функция dateadd нуждается в корректировке, но действительно приятно, спасибо.

2. @royca . , , я это исправил.

Ответ №2:

Выбор записей на основе значений в других записях является сложной задачей. Используйте коррелированный подзапрос для извлечения значения из другой записи. Требуется поле уникального идентификатора — должен использоваться автономер. Рассмотрим:

Запрос 1:

 SELECT Orders.*, (SELECT Max(OrderDate) 
                  FROM Orders AS Dupe 
                  WHERE Dupe.CustomerID = Orders.CustomerID 
                  AND Dupe.ID < Orders.ID) AS PrevOrderDate
FROM Orders;
  

Запрос 2:
SELECT Query1.* FROM Query1 WHERE ((([OrderDate]-[PrevOrderDate])>365));

Комментарии:

1. Спасибо, я буду помнить, что запрос запроса — это вариант.