I have a requirement to create a crosstab using a database which loads only incremental records. Please consider the following sample, Table1:
DAY ACCOUNT NO SALES GENDER
1-Apr-2019 ACC01 5000 MALE
1-Apr-2019 ACC02 6000 FEMALE
1-Apr-2019 ACC03 7000 FEMALE
1-Apr-2019 ACC04 8000 MALE
2-Apr-2019 ACC01 7500 MALE
2-Apr-2019 ACC02 4000 FEMALE
2-Apr-2019 ACC03 10000 FEMALE
2-Apr-2019 ACC04 20000 MALE
3-Apr-2019 ACC01 8500 FEMALE
3-Apr-2019 ACC05 3500 FEMALE
4-Apr-2019 ACC02 9500 FEMALE
4-Apr-2019 ACC06 3600 FEMALE
4-Apr-2019 ACC07 4800 MALE
5-Apr-2019 ACC01 15000 FEMALE
5-Apr-2019 ACC03 12500 FEMALE
Table1 entries explained below:
1st April there are 4 accounts with their sale nos and gender of the account holder.
On 2nd April, there is some change in sale nos for all the accounts and thus they have been loaded.
But on 3rd April, we only load incremental accounts. As can be seen, the sales of ONLY ACC01 has changed and also there is a new account ACC05. Thus only these 2 accounts will be loaded.
Again on 4th April, existing account ACC02 has an increase in sale from its previous value and thus it gets loaded. Along with this, there are 2 new accounts, ACC06 and ACC07 which also gets loaded.
Finally on 5th April, we load existing accounts which have change in sale nos from their last value.
Now, I have to do a Daily MIS reporting and the result should be as follows, considering All my Accounts are Active as on 5th April 2019.
NO OF ACCOUNTS is actually the count of the Active Accounts at the end of each Day.
The above list Report 1, I was able to achieve using the following sub-query using Cognos Query/SQL items in Report Studio:
SELECT DISTINCT D1.DAY, (SELECT COUNT(DISTINCT D2.ACCN_NO) FROM
DAILY_TABLE D2 WHERE D2.DAY <= D1.DAY) AS NO_OF_ACCOUNTS FROM
DAILY_TABLE D1 GROUP BY D1.DAY
Now, my requirement is to generate the following crosstab with a cut on the Gender.
Best Regards
you can split the totals easy by self joins, but I dont get how the no of accounts
is setup. You will have to explain better.
To split up the sales you can use this
declare @sales table (salesday date, account varchar(5), sales int, gender varchar(10))
insert into @sales (salesday, account, sales, gender)
values ('20190401', 'ACC01', 5000, 'MALE'),
('20190401', 'ACC02', 6000, 'FEMALE'),
('20190401', 'ACC03', 7000, 'FEMALE'),
('20190401', 'ACC04', 8000, 'MALE'),
('20190402', 'ACC01', 7500, 'MALE'),
('20190402', 'ACC02', 4000, 'FEMALE'),
('20190402', 'ACC03', 10000, 'FEMALE'),
('20190402', 'ACC04', 20000, 'MALE'),
('20190403', 'ACC01', 8500, 'FEMALE'),
('20190403', 'ACC05', 3500, 'FEMALE'),
('20190404', 'ACC02', 9500, 'FEMALE'),
('20190404', 'ACC06', 3600, 'FEMALE'),
('20190404', 'ACC07', 4800, 'MALE'),
('20190405', 'ACC01', 15000, 'FEMALE'),
('20190405', 'ACC03', 12500, 'FEMALE')
select s.salesday,
sum(sm.sales) as sales_male,
sum(sf.sales) as sales_female
from @sales s
left join @sales sm on s.salesday = sm.salesday
and s.account = sm.account
and sm.gender = 'MALE'
left join @sales sf on s.salesday = sf.salesday
and s.account = sf.account
and sf.gender = 'FEMALE'
group by s.salesday
order by 1
the result will be
salesday sales_male sales_female
-------- ---------- ------------
2019-04-01 13000 13000
2019-04-02 27500 14000
2019-04-03 null 12000
2019-04-04 4800 13100
2019-04-05 null 27500