CREATE TABLE dbo.Purchases (date date NOT NULL,
qty int NOT NULL,
CONSTRAINT pk_Purchases PRIMARY KEY (date))
go
INSERT dbo.Purchases(date, qty)
VALUES('20210101', 100),
('20210108', 121),
('20210110', 421),
('20210206', 610),
('20210209', 521),
('20210210', 124)
go
CREATE TABLE dbo.Sales (date date NOT NULL,
qty int NOT NULL,
CONSTRAINT pk_Sales PRIMARY KEY (date))
go
INSERT dbo.Sales(date, qty)
VALUES('20210101', 95),
('20210102', 150),
('20210113', 169),
('20210201', 521),
('20210202', 148),
('20210213', 290)
go
WITH TheUnion (Month, Year, Purchases, Sales) AS (
SELECT month(date), year(date), qty, NULL
FROM dbo.Purchases
UNION ALL
SELECT month(date), year(date), NULL, qty
FROM dbo.Sales
), aggr (Month, Year, Purchases, Sales) AS (
SELECT Month, Year, SUM(Purchases), SUM(Sales)
FROM TheUnion
GROUP BY Month, Year
)
SELECT Month, Year, Purchases, Sales,
Stock = SUM(Purchases - Sales) OVER(ORDER BY Month, Year
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM aggr
go
DROP TABLE dbo.Sales, dbo.Purchases
The first part creates the tables and populates it with the test data. Then comes the actual query.
Next time you have a question like this, we appreciate if you provide CREATE TABLE + INSERT to save us from that work.