Скользящие данные за 12 месяцев - SQL - PullRequest
0 голосов
/ 18 марта 2019

Первый пост, так что наберитесь терпения :) Я хочу подсчитать количество клиентов, которые разместили заказ в конкретном месяце, и найти количество заказов, которые они разместили в этом месяце и за 11 месяцев до этого месяца. Я действительно не уверен, с чего начать, поэтому любая помощь будет очень полезна, я также понимаю, что это довольно расплывчато, поэтому может быть несколько последующих вопросов

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

CustomerID	OrderID	  OrderDate
1234	      5678	    Dec-16
1234	      5679	    Jan-17
1235	      5680	    Jan-17

Эти данные будут возвращать результаты:

Date      CustomerCount   12MonthOrderCount
Jan 2017  2               3
Dec 2016  1               1

Спасибо!

Ответы [ 6 ]

0 голосов
/ 19 марта 2019

Вы можете использовать следующий код для получения желаемых результатов.

select count (distinct CustomerID) as 'CustomerCount', count (OrderID) as '12MonthOrderCount' 
from orders
where  (OrderDate <= '2017-01-01' AND OrderDate >= '2016-01-01')
0 голосов
/ 18 марта 2019

Полагаю, вы хотите узнать, сколько заказов в текущем месяце.

  1. выяснить, как преобразовать текст в столбцах OrderDate в тип данных DATE.

  2. используйте соответствующую арифметику даты в выражениях WHERE.

1: выражение такого типа дает вам DATE, показывающий первый день месяцаиз Mon yy Этот пример возвращает 2018-02-01.

     SELECT STR_TO_DATE(CONCAT(' 1-','Feb-18'), '%e-%b-%y') 

Таким образом, вы можете использовать этот вид запроса, чтобы получить таблицу с DATE значениями

 SELECT CustomerID, OrderID,
        STR_TO_DATE(CONCAT(' 1-',OrderDate), '%e-%b-%y') OrderDate
   FROM table

Попробуйте.Убедитесь, что он правильно работает с вашими данными.

2: используйте эти значения DATE в предложении WHERE.Для этого вам нужно знать, что функция LAST_DAY(CURDATE()) дает последний день этого месяца.И вам нужно знать, что LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH дает первый день этого месяца.

Итак, чтобы подсчитать все по идентификатору клиента в текущем месяце, сделайте это

     SELECT COUNT(*) CustomerCount, CustomerId
   FROM orders
  WHERE STR_TO_DATE(CONCAT(' 1-',OrderDate), '%e-%b-%y') >= 
                                      LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
    AND STR_TO_DATE(CONCAT(' 1-',OrderDate), '%e-%b-%y') < 
                                      LAST_DAY(CURDATE()) + INTERVAL 1 DAY
  GROUP BY CustomerId

Аналогично получимвы подсчитываете год, заканчивающийся в конце этого месяца.

     SELECT COUNT(*) 12MonthOrderCount, CustomerId
   FROM orders
  WHERE STR_TO_DATE(CONCAT(' 1-',OrderDate), '%e-%b-%y') >= 
                                      LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 YEAR
    AND STR_TO_DATE(CONCAT(' 1-',OrderDate), '%e-%b-%y') < 
                                      LAST_DAY(CURDATE()) + INTERVAL 1 DAY
  GROUP BY CustomerId

Затем вам нужно сгенерировать общий набор результатов, требуя присоединиться к этим двум подзапросам

   SELECT CustomerId, CustomerCount, 12MonthOrderCount
     FROM ( /* the query showing the full year data */ ) yr
     FROM ( /* the query showing the month data */ ) mon ON yr.CustomerId=mo.CustomerId

Youможете попробовать все это здесь.https://www.db -fiddle.com / f / riyXu8MVjJKNWfWVQLmjUG / 0

Pro tip : к настоящему времени должно стать очевидным, что сохранение дат в столбцах DATE делает жизньнамного проще, когда вы делаете такие вещи.

0 голосов
/ 18 марта 2019

Чтобы получить базовую таблицу, используйте агрегирование:

select year(orderdate), month(orderdate), count(*) as num_orders
from orders o
group by year(orderdate), month(orderdate);

Тогда за 12 месяцев вы можете сделать:

select year(orderdate), month(orderdate), count(*) as num_orders,
       (select count(*)
        from orders o2
        where year(o2.orderdate) * 100 + month(o2.orderdate) > year(o.orderdate) * 100 + month(o.orderdate) - 12 and
              year(o2.orderdate) * 100 + month(o2.orderdate) <= year(o.orderdate) * 100 + month(o.orderdate)
       ) as num_12month_orders
from orders o
group by year(orderdate), month(orderdate);

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

0 голосов
/ 18 марта 2019

Я думаю, вы хотите использовать оконную функцию для этого см. Здесь

Если бы вы их еще не проверили, я бы так и сделал.

0 голосов
/ 18 марта 2019

Поскольку в вашем вопросе много неизвестных, я позволил себе сделать множество предположений.Одним из них является то, что вы используете MSSQL.Этот код может указать вам одно возможное направление.

USE TEMPDB

DECLARE @Period INT
SET @Period = YEAR ( '20190101') * 100 + MONTH ('20190101') 

CREATE TABLE #T (CustID INT, OrderInPeriod INT, NumberOfOrders INT)

INSERT INTO #T 
SELECT CustID, 0, 0
FROM Customers

UPDATE #T
SET OrderInPeriod = 1 
FROM Orders AS O
WHERE #T.CustID = O.CustID
  AND YEAR (OrderDate) * 100 + MONTH (OrderDate) = @Period


UPDATE #T
SET NumberOfOrders = ( SELECT COUNT(*) AS Cnt FROM Orders AS O
                       WHERE #T.CustID = O.CustID
                         AND OrderDate > DATEADD (YEAR, -1, '20190101')
0 голосов
/ 18 марта 2019

если вы используете T-SQL, вы можете использовать запрос ниже

выберите t1.CusttomerIdf из таблицы1 t1 внешнее применение ( выберите top 1 t2.CId, t2.OrderId из таблицы 2 t2 где t2.CID = t1.CustomerId и [Date] = specificDate ) Д

и вам нужно выбрать количество вложенных полей.

также вы можете использовать несколько вложенных запросов выбора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...