WITH TABLE
(
cust_name,
cust ,
product
) AS --- a permanent table . list of calls by customer and prodcut(txn table)
(
VALUES
(
'ABC Corp',
1 ,
'P1'
)
,
( 'ABC Corp' , 1 , 'P2'),
( 'ABC Corp' , 1 , 'P2'),
( 'ABC Corp' , 1, 'P3') ,
( 'ABC Corp' , 1, 'P3') ,
( 'XYZ Corp', 2, 'P1') ,
( 'XYZ Corp' , 2, 'P3') ,
( 'XYZ Corp' , 2, 'P3')
)
,
prdlist
(
prdcd
) AS --- permanent table with a list of prod codes
(
VALUES
(
'P1'
)
,
('P2'),
('P3'),
('P4')
)
,
prdlist_seq
(
prdcd,
seqno
) AS
--- gives the sequence in which product columns will be generated .
-- a permanent config table or can be based on a rule
-- in this example, the sequence is alphabetically ordered by the product name
( SELECT prdcd,
rownumber() over (ORDER BY prdcd)
FROM prdlist
)
,
prdcallct1
( -- counts the number of calls grouped by custname, custid and product
CALLCT,
CNAME ,
CUSTID,
PRD ,
seqno
) AS
( SELECT COUNT(*),
CUST_NAME,
CUST ,
PRoduct ,
-100
FROM TABLE
GROUP BY CUST_NAME,
CUST ,
PRoduct
)
,
prdcallct2
(
callct,
CNAME ,
CUSTID,
PRDcd ,
seqno
) AS
-- 'inserts' 0 count from procuts 'missing' for a customer
-- there should be a more efficient way of doing prdcallct2
--
( SELECT DISTINCT 0 ,
cname ,
custid,
prdcd ,
ps.seqno
FROM prdlist_seq ps ,
prdcallct1
)
,
prdcallct
(
callct,
CNAME ,
CUSTID,
PRDcd ,
seqno
) AS -- counts the number of calls by customer by product
( SELECT SUM(callct),
cname ,
custid ,
prdcd ,
MAX(seqno)
FROM
( SELECT *
FROM prdcallct1
UNION ALL
SELECT *
FROM prdcallct2
) AS x(callct,CNAME,CUSTID, PRDcd,seqno)
GROUP BY cname ,
custid,
prdcd
)
,
temp
(
seq ,
CNAME ,
CUSTID,
prdcd ,
callctlist
) AS -- generate the call count list for products by customer
( SELECT seqno,
cname ,
custid,
prdcd ,
CAST(rtrim(CHAR(callct)) AS VARCHAR(1000))
FROM prdcallct
WHERE seqno=1
UNION ALL
SELECT seq+1 ,
t.cname ,
t.custid,
t.prdcd ,
t.callctlist
||','
||rtrim(CHAR(callct))
FROM temp t,
prdcallct p
WHERE seqno =seq+1
AND t.custid=p.custid
)
,
headerrow
(
s,
x
) AS -- generate header row
( SELECT seqno,
CAST(rtrim(prdcd) AS VARCHAR(1000))
FROM prdlist_seq
WHERE seqno=1
UNION ALL
SELECT s+1,
x
||','
||rtrim(prdcd)
FROM headerrow h,
prdlist_seq
WHERE s+1=seqno
)
,
finalresult
(
ord,
value
) AS --- print the result
( SELECT -100,
'Custid,custname,prdcd,'
||x
FROM headerrow
WHERE s=
(SELECT MAX(s)
FROM headerrow
)
UNION ALL
SELECT 100,
rtrim(CHAR(Custid))
||','
||rtrim(Cname)
||','
||rtrim(callctlist)
FROM temp
WHERE
(
custid,seq
)
IN
(SELECT custid,
MAX( seq)
FROM temp
GROUP BY custid
)
)
SELECT value
FROM finalresult
ORDER BY ord