I'm trying to pivot a table with multiple columns but i also want to append a '%' symbol for 1 row. Also i need the row to display 1 decimal point.
Original query:
select distinct a.TIME_DESC,
round(sum(a.TRX_VOLUMES)) TRx_volume,
round(sum(TARGET_TRX_VOLUMES)) Goal,
round(sum(a.TRX_VOLUMES_LY)) TRx_volume_LY,
round((sum(a.TRX_VOLUMES)/sum(c.TRX_VOLUMES_MKT))*100,1) Mkt_share
from a
join b on a.BRAND_ID=b.BRAND_ID and a.GEO_ID=b.GEO_ID
and a.TIMEPERIODTYPE=b.TIMEPERIODTYPE and a.TIME_DESC=b.TIME_DESC
join c on a.BRAND_ID=c.BRAND_ID and a.GEO_ID=c.GEO_ID
and a.TIMEPERIODTYPE=c.TIMEPERIODTYPE and a.TIME_DESC=c.TIME_DESC
where a.GEO_DESC='BC/YK' and a.type_code='B' and a.dash_brand='Copaxone'
and a.TIMEPERIODTYPE='YEAR'
group by a.TIME_DESC
For the row i am pivoting i have used
with stg1 as (select distinct a.TIME_DESC,
round(sum(a.TRX_VOLUMES)) TRx_volume,
round(sum(TARGET_TRX_VOLUMES)) Goal,
round(sum(a.TRX_VOLUMES_LY)) TRx_volume_LY,
round((sum(a.TRX_VOLUMES)/sum(c.TRX_VOLUMES_MKT))*100,1) Mkt_share
from a
join b on a.BRAND_ID=b.BRAND_ID and a.GEO_ID=b.GEO_ID
and a.TIMEPERIODTYPE=b.TIMEPERIODTYPE and a.TIME_DESC=b.TIME_DESC
join c on a.BRAND_ID=c.BRAND_ID and a.GEO_ID=c.GEO_ID
and a.TIMEPERIODTYPE=c.TIMEPERIODTYPE and a.TIME_DESC=c.TIME_DESC
where a.GEO_DESC='BC/YK' and a.type_code='B' and a.dash_brand='Copaxone'
and a.TIMEPERIODTYPE='YEAR'
group by a.TIME_DESC),
stg5 AS (SELECT * FROM (select time_desc, Mkt_share from stg1)
pivot
(SUM(Mkt_share) FOR time_desc IN ('Jan 2020', 'Feb 2020', 'Mar 2020', 'Apr 2020', 'May 2020', 'Jun 2020', 'Jul 2020', 'Aug 2020', 'Sep 2020', 'Oct 2020', 'Nov 2020', 'Dec 2020')))
select 'MS %', d.* from stg5 d
'MS%' 'Jan 2020' 'Feb 2020' 'Mar 2020'
MS % 7 6.5 7.1
I want to add a demimal for the 7 to make it a 7.0 along with a % symbol. Is that possible?
There is a way, but doesn't look pretty and is far from any "dynamic" kind of thing.
This is an ordinary pivot query:
SQL> select *
2 from
3 (select deptno, sal
4 from emp
5 )
6 pivot
7 (sum(sal) sumsal
8 for deptno in (10, 20, 30)
9 )
10 order by 1;
10_SUMSAL 20_SUMSAL 30_SUMSAL
---------- ---------- ----------
13750 10995 9400
SQL>
Suppose you want to format those salaries; then you'd do something like this:
SQL> select to_char("10_SUMSAL", '99990D0') || '%' as "10",
2 to_char("20_SUMSAL", '99990D0') || '%' as "20",
3 to_char("30_SUMSAL", '99990D0') || '%' as "30"
4 from
5 (select deptno, sal
6 from emp
7 )
8 pivot
9 (sum(sal) sumsal
10 for deptno in (10, 20, 30, 40)
11 )
12 order by 1;
10 20 30
--------- --------- ---------
13750,0% 10995,0% 9400,0%
SQL>
The answer is reformatting pivoted columns such like
TO_CHAR( "Jan 2020",'fm999G990D0','NLS_NUMERIC_CHARACTERS = ''.,''')||'%'
but do more, convert your query to a dynamic one by creating such a function :
CREATE OR REPLACE FUNCTION get_brands_volume RETURN SYS_REFCURSOR IS
recordset SYS_REFCURSOR;
sqlqry VARCHAR2(32767);
cols1 VARCHAR2(32767);
cols2 VARCHAR2(32767);
BEGIN
SELECT LISTAGG(''''||TO_CHAR(TO_DATE(level,'mm'),'Mon yyyy')||''' AS "'||
TO_CHAR(TO_DATE(level,'mm'),'Mon yyyy')||'"' ,',')
WITHIN GROUP (ORDER BY level)
INTO cols1
FROM dual
CONNECT BY level <= 12;
SELECT LISTAGG('TO_CHAR( "'||TO_CHAR(TO_DATE(level,'mm'),'Mon yyyy')||'",''fm999G990D0'',
''NLS_NUMERIC_CHARACTERS = ''''.,'''''') AS "'||
TO_CHAR(TO_DATE(level,'mm'),'Mon yyyy')||'"',',')
WITHIN GROUP (ORDER BY level)
INTO cols2
FROM dual
CONNECT BY level <= 12;
sqlqry :=
'WITH stg1 AS
(SELECT DISTINCT a.TIME_DESC,
ROUND(SUM(a.TRX_VOLUMES)) TRx_volume,
ROUND(SUM(TARGET_TRX_VOLUMES)) Goal,
ROUND(SUM(a.TRX_VOLUMES_LY)) TRx_volume_LY,
ROUND((SUM(a.TRX_VOLUMES) / SUM(c.TRX_VOLUMES_MKT)) * 100,1) Mkt_share
FROM a
JOIN b
ON a.BRAND_ID = b.BRAND_ID
AND a.GEO_ID = b.GEO_ID
AND a.TIMEPERIODTYPE = b.TIMEPERIODTYPE
AND a.TIME_DESC = b.TIME_DESC
JOIN c
ON a.BRAND_ID = c.BRAND_ID
AND a.GEO_ID = c.GEO_ID
AND a.TIMEPERIODTYPE = c.TIMEPERIODTYPE
AND a.TIME_DESC = c.TIME_DESC
where a.GEO_DESC = ''BC/YK''
AND a.type_code = ''B''
AND a.d ASh_brAND = ''Copaxone''
AND a.TIMEPERIODTYPE = ''YEAR''
GROUP BY a.TIME_DESC),
stg5 AS
(SELECT '||cols2||'
FROM stg1
PIVOT(
MAX(Mkt_share) FOR time_desc IN('||cols1||')
)
)';
OPEN recordset FOR sqlqry;
RETURN recordset;
END;
for the months of the current year, and then call from SQL Developer's command line
VAR rc REFCURSOR
EXEC :rc := get_brands_volume;
PRINT rc
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.