Агрегировать итоги и создавать данные за недели, когда данных не существует

#sql #sql-server #sql-server-2008-r2

#sql #sql-сервер #sql-server-2008-r2

Вопрос:

У меня есть таблица, подобная такой:

 Region     Date        Cases
France     1-1-2014      5
Spain      2-5-2014      6
France     3-5-2014      7
...
 

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

     select region, datepart(week, date) weeknbr, sum(cases) cases
    from <table>
    group by region, datepart(week, date)
    order by region, datepart(week, date)
 

Используя эту агрегированную функцию, есть ли способ вставить нулевое значение для каждого региона, когда данные за эту неделю не существуют?

таким образом, конечный результат будет выглядеть так:

 region      weeknbr      cases
France      1            5
France      2            0
France      3            0
.....
Spain       1            0
Spain       2            0 
Spain       3            0
....        
Spain       8            6
 

Я пытался создать таблицу с номерами недель, а затем объединить номера недель с моими данными, но безуспешно. В результате создается нулевое или нулевое значение для региона и случаев. Я всегда могу использовать isnull функцию, чтобы сделать случаи 0, но мне нужно учитывать каждый регион за каждую неделю. Это то, что убивает меня прямо сейчас. Возможно ли это? Если нет, с чего мне начать поиск и как мне изменить таблицы подчеркивания?

Любая помощь будет принята с благодарностью. Спасибо

Ответ №1:

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

 select r.region, w.RowId as Weeknbr, isnull(c.Cases,0)
from (
    select row_number()over(order by name) as RowID
    from master..spt_values
    ) w
    cross join (
        select region
        from <table>
        group by region
    ) r
    left join 
        select region, datepart(week, date) weeknbr, sum(cases) cases
        from <table>
        group by region, datepart(week, date)
        order by region, datepart(week, date)
    ) c on (w.RowID <= 53 and w.RowID = c.Weeknbr and r.region = c.region)
 

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

1. Потрясающе! Большое вам спасибо! Потребовалась небольшая настройка, но ваша логика была правильной.

Ответ №2:

Вам нужна таблица date_list и таблица region_list. Перекрестное соединение таблиц измерений для получения всех комбинаций дат и регионов, а затем левое соединение с вашей таблицей фактов.

 SELECT
  d.date,
  r.region,
  t.cases
FROM date_list d
CROSS JOIN region_list r
LEFT JOIN date_region t ON d.date = t.date AND r.region = t.region