Количество заказов клиентов по месяцам, со всеми перечисленными клиентами, даже если у клиента не было заказов в течение месяца, в одном операторе SQL?

Получите список всех итогов заказов клиентов по месяцам, и, если у клиента нет заказов в данном месяце, включите строку для этого месяца с 0 в качестве общей суммы заказа. В одном заявлении? Итоги уже рассчитаны, нет необходимости в статистической функции.

Использование функции объединения допустимо.

Данный список заказов клиентов по месяцам:

create table orders (cust char(1), month num, exps num);
insert into orders
    values('a', 1, 5)
    values('b', 2, 4)
    values('c', 1, 8);

И список клиентов:

create table custs(cust char(1));
insert into custs
    values('a')
    values('b')
    values('c')
    values('d');

Сгенерируйте эту таблицу:

cust, month, exps
 a, 1, 5
 a, 2, 0
 b, 1, 0
 b, 2, 4
 c, 1, 8
 c, 2, 0
 d, 1, 0
 d, 2, 0

2 ответа

Решение
select or1.cust, a.[month], sum(coalesce(or2.[exps], 0)) as exps
from (
    select 1 as[month] union all select 2
) a cross join (select distinct cust from custs) or1
left join orders or2 on or2.[month] = a.[month] and or2.cust = or1.cust
group by or1.cust, a.[month]
order by or1.cust,a.[month]

Sqlfiddle

И еще один вариант с подбором всех существующих месяцев со стола. Результаты одинаковы для наших тестовых данных:

select or1.cust, a.[month], sum(coalesce(or2.[exps], 0)) as exps
from (
    select distinct [month] from orders
) a cross join (select distinct cust from custs) or1
left join orders or2 on or2.[month] = a.[month] and or2.cust = or1.cust
group by or1.cust, a.[month]
order by or1.cust,a.[month]

Sqlfiddle

Создание декартового произведения клиентов и месяцев было первой трещиной в яйце... и затем левым соединением / объединением с результатом.

select all_possible_months.cust,
       all_possible_months.month,
       coalesce(orders.exps,0) as exps
from
       (select order_months.month,
          custs.cust
       from
          (select distinct month
           from
             orders
           ) as order_months,
          custs
        ) all_possible_months
left join
        orders on(
             all_possible_months.cust = orders.cust and
             all_possible_months.month = orders.month
             );
Другие вопросы по тегам