Как я могу определить события, которые произошли в последующие годы? - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь выяснить, произошло ли событие в течение трех последовательных предыдущих лет по месяцам. Например:

Item     Type      Month      Year
Hat        S         May       2015
Shirt      P         June      2015
Hat        S         June      2015
Hat        S         May       2016
Shirt      P         May       2016
Hat        S         May       2017

Мне интересно узнать, какой предмет был куплен / продан три года подряд в одном и том же месяце. Шляпа была продана в мае 2015, 2016 и 2017 годов; поэтому я хотел бы определить это. Рубашка была куплена в июне 2015 года и мае 2016 года. Так как это разные месяцы подряд, она не подпадает под квалификацию.

По сути, я хочу, чтобы он мог оглянуться назад на 3 года и идентифицировать те покупки / продажи, которые повторялись в один и тот же месяц каждый год, предпочтительно с помощью переменной индикатора.

Я попробовал следующий код:

select distinct a.*
from dataset as a inner join dataset as b 
on a.type = b.type
and a.month = b.month
and a.item = b.item
and a.year = b.year-1 
and a.year = b.year-2;

Я хочу получить:

Item     Type      Month      Year
Hat        S         May       2015
Hat        S         May       2016
Hat        S         May       2017

Полагаю, мне следует добавить, что мои данные длиннее, чем 2015-2017 годы. Он охватывает 10 лет, но я хочу посмотреть, есть ли какие-нибудь 3 последовательных года (или больше) в пределах этого 10-летнего периода.

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Вот пример, который будет проверять, произошел ли какой-либо элемент в последовательные годы, и перечислять все из исходной таблицы, которая соответствует как минимум двум последовательным годам:

DECLARE @table TABLE
(
    Item NVARCHAR(MAX),
    Type CHAR,
    Month NVARCHAR(MAX),
    Year INT
)

INSERT INTO @table VALUES
('Hat','S','May','2015'),
('Shirt','P','June','2015'),
('Hat','S','June','2015'),
('Hat','S','May','2016'),
('Shirt','P','May','2016'),
('Hat','S','May','2017')

SELECT * FROM @table
WHERE CONCAT(Item,Month) IN 
(
    SELECT CONCAT(group1.Item, group1.Month) FROM
    (
        SELECT Item,Year,Month FROM @table
        GROUP BY Year, Item, Month
    ) group1
    FULL OUTER JOIN 
    (
        SELECT Item,Year,Month FROM @table
        GROUP BY Year, Item, Month
    ) group2
    ON group1.Year = group2.Year + 1 AND group1.Item = group2.Item AND group1.Month = group2.Month
    WHERE group1.Item IS NOT NULL AND group2.Item IS NOT NULL
)
ORDER BY Item,Month,Year

Как вы можете видеть, я нашел все элементы, которыесоответствующий год + 1 в том же месяце.

ВЫХОД:

Hat S   May 2015
Hat S   May 2016
Hat S   May 2017
0 голосов
/ 18 июня 2019

Есть много способов сделать это, однако, один из способов в SQL, с ключевым пониманием того, что строки могут быть сгруппированы по Item и Month, состоит в том, чтобы ограничить Year тремя годами между 2015и 2017.Для того, чтобы претендовать на 3 последовательных, количество различных значений года в группе должно быть 3. Такие критерии будут обрабатывать данные с повторением, например, группа с 3 шляпами S-типа и 3 шляпами P-типа.

select item, type, month, year
from have
where year between 2015 and 2017
group by item, month
having count(distinct year) = 3
order by item, type, month, year

Для более общей проблемы идентификации прогонов в группе шаг данных SAS очень удобен и эффективен.Метод последовательного цикла DOW сначала зацикливается на диапазоне строк на основе некоторого условия, в то время как вычисляется групповая метрика - в данном случае последовательная длина года.Вторая перебирает те же строки и использует метрику группы.

Рассмотрим этот пример, в котором rungroup вычисляется на основе годовой смежности элемента / месяца.Как только группы запуска установлены, применяется метод двойного Доу.

data have;
  do comboid = 1 to 1000;
    itemid = ceil(10 * ranuni(123));
    typeid = ceil(2* ranuni(123));
    month = ceil(12 * ranuni(123));
    year = 2009 + floor (10 * ranuni(123));
    output;
  end;
run;

proc sort data=have;
  by itemid month year;
run;

data have_rungrouped;
  set have;
  by itemid month year;

  rungroup + (first.month or not first.month and year - lag(year) > 1);
run;

data want;
  do index = 1 by 1 until (last.rungroup);
    set have_rungrouped;
    by rungroup;

    * distinct number of years in rungroup;
    years_runlength = sum (years_runlength, first.rungroup or year ne lag(year));
  end;

  do index = 1 to index;
    set have_rungrouped;
    if years_runlength >= 3 then output;
  end;
run;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...