Вы можете получить идею из приведенного ниже кода, не можете быть протестированы и нуждаются в корректировке наверняка. Запрос получает записи attr, лучше сохранить некоторые результаты во временных таблицах.
-- Get the last Attr month for each user,
;WITH cteA
AS
(
SELECT Person,MAX(Tdate) AS LastAttrDate
FROM tblTRX
WHERE tType=N'ATTR'
GROUP BY Person
),
-- first and last transaction for each user
cteT
AS
(
SELECT Person,CONVERT(DATE,LEFT(CONVERT(nvarchar(30),MAX(Tdate),120),7)+N'-01'),120) AS LastTrxDate,
CONVERT(DATE,LEFT(CONVERT(nvarchar(30),MIN(Tdate),120),7)+N'-01'),120) AS FirstTrxDate
FROM tblTRX
WHERE tType<>N'ATTR'
GROUP BY Person
),
-- calculate the month range to insert
cteM
AS
(
SELECT T.Person, CASE WHEN A.LastAttrDate IS NULL TEHN T.FirstTrxDate ELSE DATEADD(MONTH,1,A.LastAttrDate) AS StartMonth,
T.LastTrxDate AS EndMonth
FROM cteA A
RIGHT JOIN cteT T
ON A.Person=T.Person
),
-- recursively generates the months
cteAM
(
SELECT Person,StartMonth,DATEADD(Month,1,StartMonth) AS EndMonth, EndMonth AS LastTrxMonth
FROM cteM
WHERE EndMonth>=StartMonth
UNION ALL
SELECT Person,DATEADD(Month,1,StartMonth),DATEADD(Month,1,EndMonth),LastTrxMonth
FROM cteAM
WHERE LastTrxMonth>=StartMonth
),
-- the inventory to do the cal
cteIn
(
SELECT A.Person,MIN(T.Tdate) AS InvDate
FROM tbTRX T
INNER JOIN cteAM A
ON T.Person=A.Person
AND T.TDate >=A.StartMonth
AND T.TDate<A.EndMonth
GROUP BY A.Person
)
SELECT A.Person,NULL AS Counter, A.Attr AS Transaction, M.StartMonth AS TDate, 'ATTR' AS Ttype, T.Inventory + A.Attr AS Inventory
FROM tbTRX T
INNER JOIN cteIn I ON T.Person=I.Person AND T.TDate=I.InvDate
INNER JOIN tblATTR A ON A.Person=I.Person
INNER JOIN cteAM M ON M.Person=A.Person