В нашей базе данных SQL Server 2016 у нас есть таблица Payments
, в которой записываются ежемесячные платежи, сделанные нашими клиентами, но поскольку они не обязательно платят каждый месяц, у нас могут отсутствовать данные за месяц.
Теперь мне нужно вставить отсутствующие данные ежемесячного платежа (т.е. нулевой платеж) для каждого клиента в отчет SSRS, потому что бизнес хочет видеть в этом отчете каждый месяц, чтобы оценить частоту платежей клиентов.
Итак, в приведенном ниже операторе SQL я сначала создаю табличную переменную и вставляю строку для каждого месяца и нулевую сумму платежа. Затем я создал пример данных оплаты с идентификатором клиента, месяцем и суммой. Что мне тогда нужно сделать, так это получить 12 записей для каждого клиента, по одной на каждый месяц, с указанием либо оплаты, совершенной в этом месяце, либо 0.
-- Dummy monthly payment data to use for missing months
DECLARE @DummyPayments TABLE
(
MonthNumber INT,
Payment MONEY
)
INSERT INTO @DummyPayments
select 1,0 union
select 2,0 union
select 3,0 union
select 4,0 union
select 5,0 union
select 6,0 union
select 7,0 union
select 8,0 union
select 9,0 union
select 10,0 union
select 11,0 union
select 12,0
-- This (much simplified) data would come from our Payments table
DECLARE @CustomerPayments TABLE
(
CustomerID INT,
MonthNumber INT,
Payment MONEY
)
-- Example customer 1 made payment in months 1,3,6,9
insert into @CustomerPayments values(1,1,100);
insert into @CustomerPayments values(1,3,120);
insert into @CustomerPayments values(1,6,140);
insert into @CustomerPayments values(1,9,95);
-- Example customer 2 made payment in months 2,5,10,12
insert into @CustomerPayments values(2,2,80);
insert into @CustomerPayments values(2,5,90);
insert into @CustomerPayments values(2,10,130);
insert into @CustomerPayments values(2,12,105);
-- Now I want to join real payments with dummy/missing payments
-- to get payment data for each month in the year.
with cust as
(
select distinct CustomerID
from @CustomerPayments
)
select * from @CustomerPayments cp
union
select c.CustomerID,
(select dp.MonthNumber
from @DummyPayments dp
where dp.MonthNumber not in (select cp.MonthNumber from @CustomerPayments cp where cp.CustomerID = c.CustomerID)),
0
from cust c
Когда я запускаю его, я получаю сообщение об ошибке
Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.
Я думал, что с помощью объединения будет работать, и я понимаю, что ошибка говорит мне, что я получаю слишком много результатов в каждом подзапросе, но если не использовать курсор, я не могу понять, как это сделать. Возможно, я слишком усложняю это, но если кто-нибудь сможет мне помочь, я буду признателен.