Задача

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

1.Выбирается самый неустойчивый месяц, у которого за все годы разность между наименьшим и наибольшим количеством валют, в которых заключались сделки, была самой большой.

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

  январь февраль
2001 1 2
2002 1 2
2003 1 3
2004 1 4
2005 1 5
2006 1 6
2007 1 7
2008 1 8
2009 1 9
2010 6 9
 
max 6 9
min 1 2
max – min 5 7
 
среднее avg 1.5 5.5
наибольшее
отклонение
от среднего
4.5 3.5

Пример

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

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

Видно, что наименьшее число валют, задействованное в феврале равно двум (2001, 2002), а наибольшее — девяти (2009, 2010). Разность между наибольшим и наименьшим значениями равна семи.
В январе наибольшее значение равно шести (2010), наименьшее значение равно единице (остальные годы), разность равна пяти.
То есть, по условиям задачи более неустойчивым месяцем получается февраль, поскольку его разность между наибольшим и наименьшим значениями больше, чем в январе.

С другой стороны, число используемых валют за десять лет в среднем составляет:
в январе — полторы валюты,
в феврале — пять с половиной.
Наибольшее отклонение от среднего значения в январе равно четырём с половиной (2010), а в феврале — трём с половиной (2001, 2002, 2009, 2010). То есть, по условиям задачи более устойчивым месяцем снова выходит февраль, поскольку его наибольшее отклонение от среднего значения меньше, чем в январе.

Решение на языке SQL


-- временная таблица для хранения кодов валют за каждый месяц, в которых заключались сделки
declare @tt table(year_ char(4), month_ nvarchar(10), currency int)
-- по каждому месяцу записываем все валюты в которых заключались сделки с магазинами
insert into @tt
  select distinct t.CalendarYear, t.EnglishMonthName, r.CurrencyKey
  from FactResellerSales r inner join DimTime t
       on r.OrderDateKey = t.TimeKey
  group by t.EnglishMonthName, t.CalendarYear, r.CurrencyKey
  order by t.CalendarYear, t.EnglishMonthName, r.CurrencyKey

-- в ту же таблицу по каждому месяцу записываем все валюты в которых заключались сделки по интернету
insert into @tt
  select distinct t.CalendarYear, t.EnglishMonthName, r.CurrencyKey
  from FactInternetSales r inner join DimTime t
       on r.OrderDateKey = t.TimeKey
  group by t.EnglishMonthName, t.CalendarYear, r.CurrencyKey
  order by t.CalendarYear, t.EnglishMonthName, r.CurrencyKey

--select * from @tt

-- подсчитываем количество валют за каждый месяц
declare @tc table(year_ char(4), month_ nvarchar(10), currency_count real)
insert into @tc
  select year_, month_, 'num_cur' = count(distinct currency) 
    from @tt                 --where month_='August' and year_='2001'
  group by year_, month_     --order by year_, month_

--select * from @tc


-- вычисляем наибольшее и наименьшее количество валют за все годы в каждом месяце,
-- а также разность между наибольшим и наименьшим числом
declare @tm table( month_ nvarchar(10), 
        mn real, mx real, 
        mx_mn real)
insert into @tm
     select month_, 
            min(currency_count), 
            max(currency_count),
            max(currency_count) - min(currency_count)
     from @tc 
     group by month_

--select * from @tm

declare @max_diff real;
set @max_diff = (select max(mx_mn) from @tm)

-- Находим и показываем самый неустойчивый за все годы месяц 
-- по количеству использованных в сделках валют, 
-- то есть, такой месяц года, у которого наибольшая разность между минимальным
-- и максимальным числом задействованных валют была самой большой
select month_, mx_mn from @tm where mx_mn = @max_diff;

----------------------------------

-- находим среднее значение используемых валют для каждого месяца
declare @t_av table( month_ nvarchar(10), av real);
insert into @t_av
           select month_, avg(currency_count) from @tc 
group by month_


--select * from @t_av

-- для каждого месяца по всем годам находим абсолютное значение отклонения 
-- числа используемых валют от среднего значения числа используемых валют за все годы
declare @tc_av table(year_ char(4), 
          month_ nvarchar(10), cc real, av real, av_c real)
insert into @tc_av
        select c.year_, c.month_, currency_count, av, abs(currency_count - av)
        from @tc c inner join @t_av a on c.month_ = a.month_

--select * from @tc_av
--order by month_, year_


-- для каждого месяца находим наибольшее значение отклонения от среднего значения
declare @tma table( month_ nvarchar(10), mxd real)
insert into @tma
   select month_, max(av_c) from @tc_av group by month_

--select * from @tma

-- находим самое маленькое наибольшее отклонение
declare @min_diff real;
set @min_diff = (select min(mxd) from @tma)

-- Находим и показываем месяц, у которого за все годы 
-- самое маленькое наибольшее отклонение числа использованных валют от
-- среднего значения числа использованных валют в этом месяце за все годы
select month_, mxd from @tma where mxd = @min_diff;

/*
--===============================================
--===============================================
--Поскольку месяцев всего двенадцать, можно для наглядности собрать данные по каждому месяцу 
--в общую таблицу с такими полями:
--  месяц, наибольшее число валют, наименьшее число валют, 
--  разность, среднее, набольшее отклонение от среднего
declare @tfull table(month_ nvarchar(10), max_ real, min_ real, max_min real, avg_ real, maxdiff real)
insert into @tfull
select m.month_, m.mx, m.mn, m.mx_mn, av.av, ma.mxd
from @tm as m
           inner join
     @t_av as av   on m.month_ = av.month_
           inner join
     @tma as ma    on av.month_ = ma.month_

select * from @tfull
*/