I have a requirement to show formatted data in a report. I am using three tables where one adds new users, second one for their payments and the last one for if any user resigns. So here are the sample tables and default data:
CREATE TABLE [dbo].[Entry]
(
[EmpId] [int] IDENTITY(1,1) NOT NULL,
[EmpName] [nvarchar](40) NULL,
[Address] [nvarchar](100) NULL,
[Email] [nvarchar](20) NULL,
[EntryDate] [datetime] NULL
)
INSERT [dbo].[Entry] ([EmpId], [EmpName], [Address], [Email], [EntryDate])
VALUES (1, N'John', N'On Earth', N'john@abc.com', CAST(0x0000A58000000000 AS DateTime)),
(2, N'Jack', N'On Earth', N'jack@abc.com', CAST(0x0000A5A800000000 AS DateTime)),
(3, N'Jessi', N'On Earth', N'jessi@abc.com', CAST(0x0000A5CF00000000 AS DateTime)),
(4, N'Jackson', N'On Earth', N'jackson@abc.com', CAST(0x0000A5E400000000 AS DateTime))
CREATE TABLE [dbo].[Payment]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[EmpId] [int] NULL,
[Payment] [float] NULL,
[PayDate] [datetime] NULL
)
INSERT [dbo].[Payment] ([Id], [EmpId], [Payment], [PayDate])
VALUES (1, 1, 2000, CAST(0x0000A61800000000 AS DateTime)), (2, 1, 2000, CAST(0x0000A63600000000 AS DateTime)),
(3, 1, 2000, CAST(0x0000A65500000000 AS DateTime)), (4, 1, 2000, CAST(0x0000A67400000000 AS DateTime)),
(5, 2, 4000, CAST(0x0000A5DB00000000 AS DateTime)), (6, 2, 4000, CAST(0x0000A5F900000000 AS DateTime)),
(7, 2, 4000, CAST(0x0000A61800000000 AS DateTime)), (8, 2, 4000, CAST(0x0000A63600000000 AS DateTime)),
(9, 2, 4000, CAST(0x0000A65500000000 AS DateTime)), (10, 2, 4000, CAST(0x0000A67400000000 AS DateTime)),
(11, 2, 4000, CAST(0x0000A69200000000 AS DateTime)), (12, 3, 6000, CAST(0x0000A65500000000 AS DateTime)),
(13, 3, 6000, CAST(0x0000A67400000000 AS DateTime)), (14, 4, 8000, CAST(0x0000A7FF00000000 AS DateTime)),
(15, 4, 8000, CAST(0x0000A98B00000000 AS DateTime))
CREATE TABLE [dbo].[Resign]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[EmpId] [int] NULL,
[ResignDate] [datetime] NULL,
[Reason] [nchar](10) NULL
)
INSERT [dbo].[Resign] ([Id], [EmpId], [ResignDate], [Reason])
VALUES (1, 1, CAST(0x0000A69B00000000 AS DateTime), N'Resigned '),
(2, 2, CAST(0x0000A6C400000000 AS DateTime), N'Resigned')
The required output is as follows that'll be year-wise:
Year 2015
Month - Jan - Feb - Mar - Apr - May - Jun - Jul - Aug - Sep - Oct - Nov - Dec
Opening - 10 - 10 - 10 - 12 - 12 - 12 - 12 - 12 - 12 - 12 - 8 - 8 //Total no. of employee
Add - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 //Newly added
Left - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 4 - 0 - 0 //Resigned
Closing - 10 - 10 - 12 - 12 - 12 - 12 - 12 - 12 - 12 - 8 - 8 - 8 //Closing Total
Year 2016
Month - Jan - Feb - Mar - Apr - May - Jun - Jul - Aug - Sep - Oct - Nov - Dec
Opening - 8 ----Goes on in the similar way
Add -----
Left ----
Closing ----
So this is clear how the data should be shown in the report. Though I am aware of the grouping year-wise in the report and have tried similar to show the data month-wise as follows:
SELECT
DATEPART(YYYY, Q.PayDate) [YEAR],
COUNT(m.EmpId) Total,
SUM(CASE WHEN DATENAME(MONTH, m.EntryDate) = 'January' THEN 1 ELSE 0 END) [JAN],
SUM(CASE WHEN DATENAME(MONTH, m.EntryDate) = 'February' THEN 1 ELSE 0 END) [FEB]
FROM
Entry m
INNER JOIN
Payment q ON Q.EmpId = M.EmpId
LEFT JOIN
Resign OUT ON OUT.EmpId = m.EmpId
WHERE
m.EmpId NOT IN (SELECT DISTINCT p.EmpId FROM Resign p)
AND m.EmpId IN (SELECT DISTINCT k.EmpId FROM Payment k)
GROUP BY
DATEPART(YYYY, Q.PayDate), DATEPART(MM, m.EntryDate);
The above query returns something as follows:
YEAR Total JAN FEB
--------------------
2016 2 0 0
2017 1 0 0
2018 1 0 0
But I am not sure how can I show the newly added as well resigned users with the opening in the same query row-wise as the sample given?
N.B: I am open to any query languages. So expecting your ideas to implement it in an appropriate way.