SQL Pivot??
I am not sure I want yto do pivot so looking for some other option to change rows to column. So I have ,
R(M) Measure Metrc MEtrcDesc
2 $ 04
APS
3 Units 05
CAN
3 Units 06
PRS
2 Units 07
APL
I have more than million rows in my database where I need to change these to:
MetrcDesc 04$ 04Units
05$ 05Units 06$ 06Units 07$ 07Units
APS 2
NULL NULL NULL NULL NULL
NULL NULL
CAN NULL
NULL NULL 3 NULL ULL
NULL
PRS NULL
NULL NULL NULL NULL 3 ULL NULL
SPPandey
Try
-- code #1 - static
;with
T2 as (
SELECT MetrcDesc, Metrc + Measure as MetrcMeasure, [R(M)]
from table
--where ...
SELECT MetrcDesc, [04$], [04Units], [05$], [05Units], [06$], [06Units], [07$], [07Units]
from T2
pivot (sum([R(M)]) for MetrcMeasure in ([04$], [04Units], [05$], [05Units], [06$], [06Units], [07$], [07Units])) as P;
and
-- code #2 v3 - dynamic
declare @SQLcode varchar(1200), @MetrcMeasureV varchar(500);
set @MetrcMeasureV=
STUFF((SELECT ',' + quotename(T.Metrc + M.Measure) as MetrcMeasure
from (SELECT distinct Metrc from table) as T
cross join (values ('$'),('Units')) as M(Measure)
order by MetrcMeasure
for XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @SQLcode= ';with ' +
'T2 as ( ' +
'SELECT MetrcDesc, Metrc + Measure as MetrcMeasure, [R(M)] ' +
' from table ' +
--' where ... ' +
') '+
'SELECT MetrcDesc, ' + @MetrcMeasureV +
' from T2 ' +
' pivot (sum([R(M)]) for MetrcMeasure in (' + @MetrcMeasureV + ')) as P;';
--print @SQLcode;
exec(@SQLcode);
José Diz Belo Horizonte, MG - Brasil
Similar Messages
-
Can we use multiple "pivot_for_clauses" in 11g SQL PIVOT
Can we use multiple "pivot_for_clauses" in 11g SQL PIVOT. Below SQL is an example of what I am trying to do - In this case instead of using JOIN, can I have three pivot_for_clauses in the same sql?
SQL:
MERGE INTO Test_1 dest
USING (SELECT P1.company_id,trunc(sysdate) as load_date,num_logins,......
FROM (SELECT company_id,action_type_id
FROM Testauditinfo_1 where trunc(audit_date_time)=trunc(sysdate)-1) a
PIVOT (count(action_type_id) FOR (action_type_id) IN ((1) as num_logins,(2) as num_logouts,(61) as
num_logins_from_mobile_device,(16) as num_pref_changed,....)) P1
JOIN
(SELECT company_id,action_type_id,tx_type_id
FROM Testauditinfo_1 where trunc(audit_date_time)=trunc(sysdate)-1) a
PIVOT (count(action_type_id) FOR (action_type_id,tx_type_id) IN ((3,4) AS add_invoice, (4,4) AS
edit_invoice,(3,3) as num_checks,(3,47) as num_paychecks,(3,7) as num_recvd_payments,(3,9) as num_bills,
(3,35) as num_estimates,(3,46) as num_purchase_orders)) P2
on P1.company_id=P2.company_id
JOIN
(SELECT company_id,action_type_id,list_type_id
FROM Testauditinfo_1 where trunc(audit_date_time)=trunc(sysdate)-1) a
PIVOT (count(action_type_id) FOR (action_type_id,list_type_id) IN ((3,2) AS num_items,(3,1) as
num_accounts,(3,4) as num_employees,(3,6) as num_customers,(3,14) as num_memorized_reports)) P3
on P2.company_id=P3.company_id
left outer JOIN
(SELECT company_id,create_date,count(*) as num_logos
FROM qbo.companylogos_1 group by company_id,create_date having trunc(create_date)=trunc(sysdate)-1) P4
on P3.company_id=P4.company_id
ORDER BY P1.company_id) source
ON ((dest.company_id = source.company_id) and (dest.load_date = source.load_date))WHEN MATCHED THEN
UPDATE SET dest.num_items = source.num_items where 1=2
WHEN NOT MATCHED THEN
INSERT (dest.company_id,.....) values (source.company_id,.....);Maybe
MERGE INTO Test_1 dest
USING (SELECT P1.company_id,trunc(sysdate) as load_date,num_logins,......
FROM (select *
from (SELECT company_id,action_type_id
FROM Testauditinfo_1
where trunc(audit_date_time) = trunc(sysdate)-1
) a
PIVOT (count(action_type_id)
FOR (action_type_id) IN ((1) as num_logins,
(2) as num_logouts,(61) as num_logins_from_mobile_device,
(16) as num_pref_changed,....
) P1
JOIN
(select *
from (SELECT company_id,action_type_id,tx_type_id
FROM Testauditinfo_1
where trunc(audit_date_time) = trunc(sysdate)-1
) a
PIVOT (count(action_type_id)
FOR (action_type_id,tx_type_id) IN ((3,4) AS add_invoice,
(4,4) AS edit_invoice,
(3,3) as num_checks,
(3,47) as num_paychecks,
(3,7) as num_recvd_payments,
(3,9) as num_bills,
(3,35) as num_estimates,(3,46) as num_purchase_orders
) P2
on P1.company_id = P2.company_id
JOIN
(select *
from (SELECT company_id,action_type_id,list_type_id
FROM Testauditinfo_1
where trunc(audit_date_time) = trunc(sysdate)-1
) a
PIVOT (count(action_type_id)
FOR (action_type_id,list_type_id) IN ((3,2) AS num_items,
(3,1) as num_accounts,
(3,4) as num_employees,
(3,6) as num_customers,
(3,14) as num_memorized_reports
) P3
on P2.company_id = P3.company_id
left outer JOIN
(SELECT company_id,create_date,count(*) as num_logos
FROM qbo.companylogos_1
group by company_id,create_date
having trunc(create_date) = trunc(sysdate)-1
) P4
on P3.company_id = P4.company_id
ORDER BY P1.company_id
) source
ON ((dest.company_id = source.company_id) and (dest.load_date = source.load_date))
WHEN MATCHED
THEN UPDATE SET dest.num_items = source.num_items where 1 = 2
WHEN NOT MATCHED
THEN INSERT (dest.company_id,.....)
values (source.company_id,.....)Did you try it ?
Regards
Etbin -
Hello,
Can anyone help me write a SQL pivot statement using 11G to do the following?:
Table columns
=========
Deliverable
Phase (For simplicity we'll make the total possible Phase values equal 1 to 13)
Delv_IN_Phase_Y_N Char(3) values 'Yes' or 'No'
I want to make a matrix with these 3 columns in the above table (in reality a complex view) :
- Deliverable is first column.
- Next 13 column headers display 1 to 13 (the posiible values contained in the 'Phase' column).
- The matrix values under the 'Phase' Column headers are the Yes/No values held in the Delv_in_Phase column.
Deliverable Phase 1 Phase 2 Phase 3 Phase 4 ......... Phase 13
=========================================================
Product Market Plan Yes No No Yes No
Bid Plan No Yes No ...........................................
Contract Summary ................................................................................
Quality Plan .................................................................................
Thanks for any help in advance.
CarolJust a simple example based on what I could grasp from your table description.
I assume you can't have more than 1 value (either 'yes' or 'no' for a given deliverable in each phase).
Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as fsitja
SQL> with t as (
2 select 'Product Market Plan' deliverable, 1 phase, 'NO' Delv_IN_Phase_Y_N from dual union all
3 select 'Product Market Plan' deliverable, 2 phase, 'YES' Delv_IN_Phase_Y_N from dual union all
4 select 'Product Market Plan' deliverable, 3 phase, 'YES' Delv_IN_Phase_Y_N from dual union all
5 select 'Bid Plan', 1, 'YES' from dual union all
6 select 'Bid Plan', 2, 'NO' from dual union all
7 select 'Bid Plan', 3, 'NO' from dual union all
8 select 'Contract Summary', 1, 'NO' from dual union all
9 select 'Contract Summary', 2, 'NO' from dual union all
10 select 'Contract Summary', 3, 'YES' from dual union all
11 select 'Quality Plan', 1, 'YES' from dual union all
12 select 'Quality Plan', 2, 'YES' from dual union all
13 select 'Quality Plan', 3, 'NO' from dual)
14 -- END OF SAMPLE DATA
15 SELECT *
16 FROM t
17 PIVOT(MAX(delv_in_phase_y_n) FOR phase IN (1 AS phase_1, 2 AS phase_2, 3 AS phase_3))
18 /
DELIVERABLE PHASE_1 PHASE_2 PHASE_3
Contract Summary NO NO YES
Bid Plan YES NO NO
Product Market Plan NO YES YES
Quality Plan YES YES NO
SQL> You can play around and expand the pivot by adding the whole 13 values inside the "FOR phase IN (val1 as column1, etc)" just thought I'd keep it simple.
=> [Documentation Reference here|http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#CHDCEJJE]
Regards. -
Dynamic SQL PIVOT not producing output?
Hey all,
Find my source code with test data scripts below. Since my production system is not connected to the inet, I had to type this
"by hand" as it were, so please pardon any mispellings. I have no way to test on my inet-enabled PC before posting.
Anyways, here's my issue: if you run the below code as PL/SQL script, it runs fine but it produces NO output (it should display a
grid of data). That is my dilemma. How to get my dynamic pivot to actually SHOW the data. So I've been experimenting with
EXECUTE IMMEDIATE, but when I use that syntax, it blows up with the error:
PLS-00321: expression 'TMPTABLE' is inappropriate as the left hand side of an assignment statement
I have provide the lines below which cause the error, but they are commented out so you can see it runs fine the 1st way (yet
displays no data) and blows up the 2nd way. I would appreciate your insights.
Thanks
DROP TABLE table1;
DROP TABLE table2;
DROP TABLE datetable;
CREATE TABLE table1
TIME_STAMP TIMESTAMP(6) DEFAULT systimestamp NOT NULL,
Id VARCHAR2(50 BYTE) NOT NULL
CREATE TABLE table2
NAME VARCHAR2(50 BYTE),
Id VARCHAR2(50 BYTE) NOT NULL
CREATE TABLE datetable
YEAR_WEEK VARCHAR2(7 BYTE),
WEEK_START_DATE DATE
INSERT INTO table1 VALUES (to_date(‘05/30/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (to_date(‘05/31/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (to_date(‘06/01/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (to_date(‘06/02/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (to_date(‘06/03/2011’,’MM/DD/YYYY’),’2’);
INSERT INTO table1 VALUES (to_date(‘06/04/2011’,’MM/DD/YYYY’),’2’);
INSERT INTO table1 VALUES (to_date(‘06/05/2011’,’MM/DD/YYYY’),’2’);
INSERT INTO table1 VALUES (to_date(‘06/07/2011’,’MM/DD/YYYY’),’2’);
INSERT INTO table1 VALUES (to_date(‘06/08/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (to_date(‘06/09/2011’,’MM/DD/YYYY’),’1’);
INSERT INTO table1 VALUES (‘Bob’,’1’);
INSERT INTO table1 VALUES (‘Gary’,’2’);
INSERT INTO table1 VALUES (‘2011-21’,to_date(‘05/23/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-22’,to_date(‘05/30/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-23’,to_date(‘06/06/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-24’,to_date(‘06/13/2011’,’MM/DD/YYYY’));
DECLARE
sql_txt VARCHAR2 (32767);
--keep the below commented for the 1st test, uncomment for 2nd test
--TYPE tmpTable IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
BEGIN
sql_txt :=
Q'{WITH got_dates AS
SELECT b.name,
COUNT(*) AS Responded,
iso.week_start_date AS week_start_date
FROM
table1 a INNER JOIN table2 b ON
(a.id = b.id) INNER JOIN datetable iso ON
((case when to_char(a.time_stamp, 'IW')='53' then to_char(cast(to_char(a.time_stamp, 'IYYY') as int)+1) || '-01' else to_char(a.time_stamp, 'IYYY-IW') end) = iso.year_week)
WHERE
(a.time_stamp >= sysdate-30)
GROUP BY
iso.week_start_date,
b.name
SELECT *
FROM got_dates
PIVOT (
SUM (Responded) FOR week_start_date IN (
FOR d_rec IN (
WITH possible_dates AS
SELECT SYSDATE + 1 - LEVEL AS time_stamp
FROM DUAL
CONNECT BY LEVEL <= 31
SELECT DISTINCT 'DATE '''
|| TO_CHAR ( c.week_start_date
, 'YYYY-MM-DD'
|| ''' AS '
|| TO_CHAR ( c.week_start_date
, 'mon_dd_yyyy'
|| CASE
WHEN DENSE_RANK () OVER (ORDER BY c.week_start_date) > 1
THEN ','
END AS txt
FROM possible_dates p
INNER JOIN datetable c ON c.year_week =
CASE
WHEN TO_CHAR ( p.time_stamp, 'IW') = '53'
THEN TO_CHAR (cast(TO_CHAR(p.time_stamp,'IYYY') AS int)+1) || '-01'
ELSE TO_CHAR ( p.time_stamp, 'IYYY-IW')
END
ORDER BY txt DESC
LOOP
sql_txt := sql_txt || ' ' || d_rec.txt;
END LOOP;
sql_txt := sql_txt || ') )';
--keep the below commented for the 1st test, uncomment for 2nd test. also, comment out the 2nd EXECUTE IMMEDIATE (only 1 at a time should be uncommented)
--EXECUTE IMMEDIATE sql_txt BULK COLLECT INTO tmpTable;
EXECUTE IMMEDIATE sql_txt;
END;Edited by: user8825851 on Oct 6, 2011 2:12 PMHi,
user8825851 wrote:
Find my source code with test data scripts below. Since my production system is not connected to the inet, I had to type this
"by hand" as it were, so please pardon any mispellings. I have no way to test on my inet-enabled PC before posting. Install an Oracle database on your PC. It's free and it's not difficult. if you're going to use this forum, whatever time you have to invest in it will pay off within a week.
http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html
Anyways, here's my issue: if you run the below code as PL/SQL script, it runs fine but it produces NO output (it should display a
grid of data)...In PL/SQL, you always have to SELECT into something.
One simple way is to open a cursor. Before running the PL/SQL code, declare a bind variable for the cursor:
VARIABLE c REFCURSOR
-- And while you're at it, do this, too
SET SERVEROUTPUT ONIn the PL/SQL code, use an OPEN statement in place of EXECUTE IMMEDIATE:
... dbms_output.put_line (sql_txt); -- For debugging only
-- EXECUTE IMMEDIATE sql_txt; -- Don't do this
OPEN :c FOR sql_txt; -- Do this instead
END;
/After the PL/SQL is finsihed, you can use PRINT to see the results:
PRINT :cIn this case, you'll get an error message because the dynamic code is incorrect. That's what the call to put_line is for: to show exactly what you're running. If there's a problem, you can examine the output, or copy it into a script, edit it and debug it.
In this case, you'll see that the dynamic SQL ends with:
PIVOT (
SUM (Responded) FOR week_start_date IN (
) )The part that's supposed to be dynamic is missing. That part is supposed to be written inside the d_rec cursor loop, but d_rec is returning no rows. That's because of the join condition:
INNER JOIN datetable c ON c.year_week =
CASE
WHEN TO_CHAR ( p.time_stamp, 'IW') = '53'
THEN TO_CHAR (cast(TO_CHAR(p.time_stamp,'IYYY') AS int)+1) || '-01'
ELSE TO_CHAR ( p.time_stamp, 'IYYY-IW')
END With the given sample data, p.time_stamp is producing values between '2011-36' and '2011-40', but the values in c.week are
INSERT INTO table1 VALUES (‘2011-21’,to_date(‘05/23/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-22’,to_date(‘05/30/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-23’,to_date(‘06/06/2011’,’MM/DD/YYYY’));
INSERT INTO table1 VALUES (‘2011-24’,to_date(‘06/13/2011’,’MM/DD/YYYY’));(I assume you meant "INSERT INTO *datetable* " above.)
Perhaps you meant LEFT OUTER JOIN instead of INNER JOIN in d_rec. -
Hi all,
I'm trying to use a PIVOT on the following data set:
ID STATUS_DESC PAY_STATUS PAID_DATE TRANSACTION_TYPE TRANSACTION_DESC DEBIT TOTAL
9876 In Progress 2nd Payment Made 11-DEC-12 19.38.57 Card Payment Payment 2 349 349
9876 In Progress 2nd Payment Made 06-DEC-12 14.33.57 Card Payment Payment 1 100 100
However I'm still getting two rows as per the below. Ideally all data should be on a single row.
ID STATUS_DESC PAY_STATUS PAYMENT_1_DATE PAYMENT_1_AMT PAYMENT_2_DATE PAYMENT_2_AMT TOTAL
9876 In Progress 2nd Payment Made 06-DEC-12 14.33.57 100 100
9876 In Progress 2nd Payment Made 11-DEC-12 19.38.57 349 349
I have constructed my pivot using the following on the outer select:
PIVOT (MAX (insert_timestamp) AS paid_date
,SUM (debit) AS amt
FOR transaction_desc IN ('Payment 1' AS payment_1,
'Payment 2' AS payment_2)) ;
I've used MAX to pivot the date and also tried using NVL on the insert_timestamp but still no luck.
Any ideas?
Thank you in advance.
Edited by: Brian1982 on Jan 28, 2013 3:43 PMBrian1982 wrote:
My desired output would be a single row.
with t as (
select 9876 id,'In Progress' status_desc,'2nd Payment Made' pay_status,to_date('11-DEC-12 19.38.57','dd-mon-rr hh24.mi.ss') paid_date,'Card Payment' transaction_type,'Payment 2' transaction_desc,349 debit,349 total from dual union all
select 9876,'In Progress','2nd Payment Made',to_date('06-DEC-12 14.33.57','dd-mon-rr hh24.mi.ss'),'Card Payment','Payment 1',100,100 from dual
select payment_1_id id,
payment_1_status_desc status_desc,
payment_1_pay_status pay_status,
payment_1_dt,
payment_1_amt,
payment_2_dt,
payment_2_amt
from t
pivot(
max(id) id,
max(status_desc) status_desc,
max(pay_status) pay_status,
max(paid_date) dt,
max(transaction_type) transaction_type,
max(debit) amt,
max(total) total
for transaction_desc in ('Payment 1' AS payment_1,'Payment 2' AS payment_2)
ID STATUS_DESC PAY_STATUS PAYMENT_1_DT PAYMENT_1_AMT PAYMENT_2_DT PAYMENT_2_AMT
9876 In Progress 2nd Payment Made 06-dec-12 14.33.57 100 11-dec-12 19.38.57 349
SQL> SY. -
Hi Experts
I recently purchased a copy of Gordon's book to help me create a pivot query based on the examples at the end which I hope to show me a set of data based on my Sales Order tables. Unfortunately I have found it a little too complex.
In my ORDR table I have 10 UDFs which relate to various statuses and dates in the sales order process.
What I would like is to see a pivot table query of the sum quanties of items at the different stages (as rows) against the dates in weeks.
In the rows would be the status UDF fields:
U_DES_STAGE
U_PRN_STAGE
U_PRS_STAGE
U_SEW_STAGE
U_EMB_STAGE
for each UDF there is an associated date UDF
U_DES_STAGE_DATE
U_PRN_STAGE_DATE
U_PRS_STAGE_DATE
U_SEW_STAGE_DATE
U_EMB_STAGE_DATE
The columns I require in the pivot table would be the UDF stage dates which are always input for the week ending Friday.
The data in the pivot should be the sum of the quantities in the sales orders rows RDR1.
Stage
W/E 14/3/2014
W/E 21/3/2014
W/E 28/3/2014
W/E 4/4/2014
W/E 11/4/2014
W/E 18/4/2014
DES
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
PRN
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
PRS
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
SEW
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
EMB
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
Sum of Qty
The problem is that I am not sure as to how to add the WHERE clause to limit the results to only the 5 items (DES% or PRN% or PRS% or SEW% or EMB%)
I would be very grateful for any assistance.
Regards
GeoffHi Gordon - you're very welcome. The content of the book is very helpful to an SQL novice!
Essentially the 10 UDF are for recording each stage of the processes involved in the sales order. there are 5 processes so each process has 2 fields - one records the initals of the staff member who is responsible and the other records the date the process is scheduled for.
We want to be able to produce a schedule to show us how many garments are scheduled on a sales order in a particular week effectively turning this table into the one below it:
Document Number
Quantity
Design - Scheduled Date
Dye Print Scheduled Date
Dye Press Scheduled Date
Dye Sewing Scheduled Date
Embroidery - Scheduled Date
Print – Scheduled Date
298835
315
12.07.10
06.09.10
300058
144
22.07.10
06.09.10
300921
29
01.10.10
302330
15
30.09.10
30.09.10
302820
460
05.10.10
302833
55
20.09.10
22.09.10
303476
86
06.10.10
06.10.10
303948
13
11.08.10
11.08.10
303982
106
26.10.10
27.10.10
304012
99
25.11.10
25.11.10
304186
6
27.08.10
27.08.10
304331
10
07.09.10
07.09.10
304382
16
29.09.10
29.09.10
304399
15
19.08.10
304556
85
01.10.10
22.10.10
304557
11
29.09.10
29.09.10
304563
8
29.09.10
29.09.10
304567
7
29.09.10
304570
19
01.10.10
22.10.10
304571
113
01.10.10
22.10.10
304576
11
29.09.10
29.09.10
304603
72
22.09.10
23.09.10
304604
86
22.09.10
23.09.10
304606
107
22.09.10
23.09.10
304608
107
22.09.10
23.09.10
304613
107
22.09.10
23.09.10
304693
12
29.09.10
29.09.10
304710
5
29.09.10
304760
6
29.09.10
29.09.10
304765
4
29.09.10
304899
42
15.09.10
304963
100
22.09.10
24.09.10
304974
719
27.09.10
29.09.10
304975
401
28.09.10
29.09.10 -
Dynamic SQL Pivoting(Converting Row to Columns)
Hi All,
I am using Oracle 9i (Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production)
and also 10g version
I am facing difficulties to find out the logic for
converting the set of values in one of the columns into the column headings for the entire query.
create TABLE my_tab ( deptno VARCHAR2(5), job VARCHAR2(50), sal NUMBER);
insert into my_tab ( deptno,JOB, sal) values ( 10, 'ANALYST', 23000);
insert into my_tab ( deptno,JOB, sal) values ( 10, 'SALESMAN', 1500);
insert into my_tab ( deptno,JOB, sal) values ( 10, 'CLERK', 3550);
insert into my_tab ( deptno,JOB, sal) values ( 20, 'SALESMAN', 700);
insert into my_tab ( deptno,JOB, sal) values ( 20, 'ANALYST', 4200);
insert into my_tab ( deptno,JOB, sal) values ( 30, 'SALESMAN', 5600);
insert into my_tab ( deptno,JOB, sal) values ( 30, 'CLERK', 12000);
insert into my_tab ( deptno,JOB, sal) values ( 30, 'ANALYST', 19000);
COMMIT;
SELECT * FROM my_tab
DEPTNO ______ JOB ________ SAL
10 ______ ANALYST ________ 23000
10 ______ SALESMAN ________ 1500
10 _______ CLERK ________ 3550
20 _______ SALESMAN ________ 700
20 _______ ANALYST ________ 4200
30 _______ SALESMAN ________ 5600
30 _______ CLERK _______ 12000
30 _______ ANALYST _______ 19000
--And I wish to convert it into this structure:
DEPTNO ________ ANALYST ________ SALESMAN _________ CLERK
10 ________ 23000 ________ 1500 _________ 3550
20 ________ 4200 ________ 700 _________ NULL
30 ________ 19000 ________ 5600 _________ 12000
It may be dynamic. i.e Later i inserted more two records into My_tab.
insert into my_tab ( deptno,JOB, sal) values ( 20, 'CLERK', 3400);
insert into my_tab ( deptno,JOB, sal) values ( 30, 'MANAGER', 48000);
So it should be dynamic.
output is like this.
DEPTNO ________ ANALYST ______ SALESMAN ______ CLERK ______ MANAMGER
10 ________ 23000 ______ 1500 ______ 3550 ______ NULL
20 ________ 4200 ______ 700 ______ 3400 ______ NULL
30 ________ 19000 ______ 5600 ______ 12000 ______ 48000
Please help me regarding this.
With warm regards,
PrasantaHi, Prasanta,
Displaying one column from many rows as many columns on one row is called Pivoting . The following thread shows the basics of how to pivot:
Help for a query to add columns
That example uses the aggregate COUNT function; you'll want SUM (or possibly MIN or MAX) instead.
Getting a dynamic number of columns requires Dynamic SQL . As a simpler alternative to pivoting and dynamic SQL, you might consider String Aggregation , where you concatenate a column from many rows into one big string, to be displayed on one row.
See the following thread for more about string aggregation and other options on pivoting into a variable number of columns:
Re: Report count and sum from many rows into many columns -
Hello,
I have the following pivot that's working properly. It's adding up purchases into monthly time frame columns. Is there anyway to add a second column called [redemptions]? Ideally, I want it to sum up monthly purchases, monthly
redemptions, then take the difference between the purchases and redemptions and call it new money. So each month would have three columns labeled 20130531 Purchases, 20130531 Redemptions, 20130531 New Money., ...., etc....
SELECT * FROM [Assets].[dbo].[Monthly]
pivot(sum(PURCHASES) for [DATE] IN
[20130531],
[20130628],
[20130731],
[20130830],
[20130930],
[20131031],
[20131129],
[20131231],
[20140131],
[20140228],
[20140331],
[20140430],
[20140530],
[20140630],
[20140731],
[20140829],
[20140930],
[20141031]
)) AS test
xpossible if you use classic crosstab method
ie like
SELECT other columns...,
SUM(CASE WHEN [DATE] = '20130531' THEN PURCHASES ELSE 0 END) AS [20130531_PURCHASES],
SUM(CASE WHEN [DATE] = '20130531' THEN REDEMPTIONS ELSE 0 END) AS [20130531_REDEMPTIONS],
SUM(CASE WHEN [DATE] = '20130628' THEN PURCHASES ELSE 0 END) AS [20130628_PURCHASES],
SUM(CASE WHEN [DATE] = '20130628' THEN REDEMPTIONS ELSE 0 END) AS [20130628_REDEMPTIONS],
SUM(CASE WHEN [DATE] = '20130731' THEN PURCHASES ELSE 0 END) AS [20130731_PURCHASES],
SUM(CASE WHEN [DATE] = '20130731' THEN REDEMPTIONS ELSE 0 END) AS [20130731_REDEMPTIONS],
SUM(CASE WHEN [DATE] = '20141031' THEN PURCHASES ELSE 0 END) AS [20141031_PURCHASES],
SUM(CASE WHEN [DATE] = '20141031' THEN REDEMPTIONS ELSE 0 END) AS [20141031_REDEMPTIONS]
FROM [Assets].[dbo].[Monthly]
GROUP BY other columns...
Please Mark This As Answer if it solved your issue
Please Mark This As Helpful if it helps to solve your issue
Visakh
My MSDN Page
My Personal Blog
My Facebook Page -
HUM ADG DYS (NIA, SIM, TRC, TRX) SMALL BRANDS (LUP, KAL,CRN,LPP,SYN)
MON TUE WED THURS FRI MON TUE WED THURS FRI MON TUE WED THURS FRI MON TUE WED THURS FRI
VENDOR
INT
QUAN
STER
LASH
OSP
HIB
PROD
I’d like to put together a query to populate the tables above,like count of recods for each vendor for each brand with the criteria for selecting within one week.
Here vendor_cd(INT,QUAN,STER,...etc),brand_cd(HUM,ADG,NIA,SIM,..eyc).we are extracting the details from file detail table whose column are like FILE_ID,FILE_RECEIPT_TS,REC_INSERT_TS,VENDOR_CD,BRAND_CD,RECORD_COUNT.
Edited by: ASHWINI89 on Mar 21, 2013 8:33 PMWelcome to the forum!!
Please consider the following when you post a question. This would help us help you better
1. New features keep coming in every oracle version so please provide Your Oracle DB Version to get the best possible answer.
You can use the following query and do a copy past of the output.
select * from v$version 2. This forum has a very good Search Feature. Please use that before posting your question. Because for most of the questions
that are asked the answer is already there.
3. We dont know your DB structure or How your Data is. So you need to let us know. The best way would be to give some sample data like this.
I have the following table called sales
with sales
as
select 1 sales_id, 1 prod_id, 1001 inv_num, 120 qty from dual
union all
select 2 sales_id, 1 prod_id, 1002 inv_num, 25 qty from dual
select *
from sales 4. Rather than telling what you want in words its more easier when you give your expected output.
For example in the above sales table, I want to know the total quantity and number of invoice for each product.
The output should look like this
Prod_id sum_qty count_inv
1 145 2 5. When ever you get an error message post the entire error message. With the Error Number, The message and the Line number.
6. Next thing is a very important thing to remember. Please post only well formatted code. Unformatted code is very hard to read.
Your code format gets lost when you post it in the Oracle Forum. So in order to preserve it you need to
use the {noformat}{noformat} tags.
The usage of the tag is like this.
<place your code here>\
7. If you are posting a *Performance Related Question*. Please read
{thread:id=501834} and {thread:id=863295}.
Following those guide will be very helpful.
8. Please keep in mind that this is a public forum. Here No question is URGENT.
So use of words like *URGENT* or *ASAP* (As Soon As Possible) are considered to be rude. -
Dynamic PIVOT in T-SQL or somewhere else?
In a
recent thread on dynamic SQL, the issue of dynamic PIVOT came up.
Dynamic PIVOT can be implemented in T-SQL with dynamic SQL:
Pivots with Dynamic Columns in SQL Server 2005
http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/
http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query
http://www.sqlusa.com/bestpractices2005/dynamicpivot/
Alternatives:
1. Enhancement by MS to the current static PIVOT which has limited use since it is not data-driven
2. Use SSRS which has built-in dynamic columns
3. Use client app
What is your opinion? Is it OK to use dynamic SQL for dynamic PIVOT?
Kalman Toth Database & OLAP Architect
SQL Server 2014 Design & Programming
New Book / Kindle: Exam 70-461 Bootcamp: Querying Microsoft SQL Server 2012solution elsewhere, for instance with Tablix in SSRS. Pivoting a result set in C# should not be too difficult
But I could do it much faster in T-SQL with dynamic SQL.
If your shop has a reporting system like SSRS and the request is for permanent report, then by all means, SSRS is the choice with built-in dynamic columns.
C#? I used to know C/C++. So that is not a choice for me. On the other hand, if you are competent in C#, then it may be a better choice, or it may not.
I'm not sure why people tend to shy away from dynamic SQL, for me, I've never had any problems or issues. Is there any specific reason for this?
Maybe the multiple single quotes like '''' in concatenation of the dynamic SQL string? When one looks at the following example, it is easy to see that dynamic SQL adds a new level of complexity to static SQL. Yet, the complexity pays off with incredible
dynamic SQL programming power.
BLOG: Building Dynamic SQL In a Stored Procedure
Code example from the blog:
/* This stored procedure builds dynamic SQL and executes
using sp_executesql */
Create Procedure sp_EmployeeSelect
/* Input Parameters */
@EmployeeName NVarchar(100),
@Department NVarchar(50),
@Designation NVarchar(50),
@StartDate DateTime,
@EndDate DateTime,
@Salary Decimal(10,2)
AS
Set NoCount ON
/* Variable Declaration */
Declare @SQLQuery AS NVarchar(4000)
Declare @ParamDefinition AS NVarchar(2000)
/* Build the Transact-SQL String with the input parameters */
Set @SQLQuery = 'Select * From tblEmployees where (1=1) '
/* check for the condition and build the WHERE clause accordingly */
If @EmployeeName Is Not Null
Set @SQLQuery = @SQLQuery + ' And (EmployeeName = @EmployeeName)'
If @Department Is Not Null
Set @SQLQuery = @SQLQuery + ' And (Department = @Department)'
If @Designation Is Not Null
Set @SQLQuery = @SQLQuery + ' And (Designation = @Designation)'
If @Salary Is Not Null
Set @SQLQuery = @SQLQuery + ' And (Salary >= @Salary)'
If (@StartDate Is Not Null) AND (@EndDate Is Not Null)
Set @SQLQuery = @SQLQuery + ' And (JoiningDate
BETWEEN @StartDate AND @EndDate)'
/* Specify Parameter Format for all input parameters included
in the stmt */
Set @ParamDefinition = ' @EmployeeName NVarchar(100),
@Department NVarchar(50),
@Designation NVarchar(50),
@StartDate DateTime,
@EndDate DateTime,
@Salary Decimal(10,2)'
/* Execute the Transact-SQL String with all parameter value's
Using sp_executesql Command */
Execute sp_Executesql @SQLQuery,
@ParamDefinition,
@EmployeeName,
@Department,
@Designation,
@StartDate,
@EndDate,
@Salary
If @@ERROR <> 0 GoTo ErrorHandler
Set NoCount OFF
Return(0)
ErrorHandler:
Return(@@ERROR)
GO
LINK:
http://www.codeproject.com/Articles/20815/Building-Dynamic-SQL-In-a-Stored-Procedure
Kalman Toth Database & OLAP Architect
SQL Server 2014 Design & Programming
New Book / Kindle: Exam 70-461 Bootcamp: Querying Microsoft SQL Server 2012 -
Setting Column Names in Dynamic Pivot Query
Hi all,
I'm having trouble setting column names in a dynamic pivot query and was wondering if someone could please help me figure out what I need to do.
To help you help me, I've setup an example scenario in my hosted account. Here's the login info for my hosted site at [http://apex.oracle.com]
Workspace: MYHOSTACCT
Username : DEVUSER1
Password : MYDEVACCTAnd, here is my test application info:
ID : 42804
Name : dynamic query test
Page : 1
Table 1: PROJECT_LIST (Alias = PL... Listing of Projects)
Table 2: FISCAL_YEAR (Alias = FY... Lookup table for Fiscal Years)
Table 3: PROJECT_FY (Alias = PF... Intersection table containing project fiscal years)
Table 4: PROJECT_FY_HEADCOUNT (Alias = PFH... Intersection table containing headcount per project and fiscal year)Please forgive the excessive normalization for this example, as I wanted to keep the table structure similar to my real application, which has much more going on.
In my sample, I have the "Select Criteria" region, where the user specifies the project and fiscal year range that he or she would like to report. Click the Search button, and the report returns the project headcount in a pivoted fashion for the fiscal year range specified.
I've got it working using a hard-coded query, which is displayed in the "Hardcoded Query" region. In this query, I basically return all years, and set conditions on each column which determines whether that column should be displayed or not based on the range selected by the user. While this works, it is not ideal, as there could be many more fiscal years to account for, and this is not very dynamic at all. Anytime a fiscal year is added to the FISCAL_YEAR table, I'd have to update this page.
So, after reading all of the OTN SQL pivot forums and "Ask Tom" pivot thread, I've been able to create a second region labeled "Dynamic Query" in which I've created a dynamic query to return the same results. This is a much more savvy solution and works great; however, the column names are generic in the report.
I had to set the query to parse at runtime since the column selection list is dynamic, which violates SQL rules. Can anyone please help me figure out how I can specify my column names in the dynamic query region to get the same column values I'm getting in the hardcoded region?
Please let me know if you need anymore information, and many thanks in advance!
MarkHi Tony,
Thanks so much for your response. I've had to study up on the dbms_sql package to understand your function... first time I've used it. I've fed my dynamic query to your function and see that it returns a colon delimited list of the column names; however, I think I need a little more schooling on how and where exactly to apply the function to actually set the column names in APEX.
From my test app, here is the code for my dynamic query. I've got it in a "PL/SQL function body returning sql query" region:
DECLARE
v_query VARCHAR2(4000);
v_as VARCHAR2(4);
v_range_from NUMBER;
v_range_to NUMBER;
BEGIN
v_range_from := :P1_FY_FROM;
v_range_to := :P1_FY_TO;
v_query := 'SELECT ';
-- build the dynamic column selections by looping through the fiscal year range.
-- v_as is meant to specify the column name as (FY10, FY11, etc.), but it's not working.
FOR i IN v_range_from.. v_range_to LOOP
v_as := 'FY' || SUBSTR(i, 3, 4);
v_query := v_query || 'MAX(DECODE(FY_NB,' || i || ',PFH_HEADCOUNT,0)) '
|| v_as || ',';
END LOOP;
-- add the rest of the query to the dynamic column selection
v_query := rtrim(v_query,',') || ' FROM ('
|| 'SELECT FY_NB, PFH_HEADCOUNT FROM ('
|| 'SELECT FY_ID, FY_NB FROM FISCAL_YEAR) A '
|| 'LEFT OUTER JOIN ('
|| 'SELECT FY_ID, PFH_HEADCOUNT '
|| 'FROM PROJECT_FY_HEADCOUNT '
|| 'JOIN PROJECT_FY USING (PF_ID) '
|| 'WHERE PL_ID = ' || :P1_PROJECT || ') B '
|| 'ON A.FY_ID = B.FY_ID)';
RETURN v_query;
END;I need to invoke GET_QUERY_COLS(v_query) somewhere to get the column names, but I'm not sure where I need to call it and how to actually set the column names after getting the returned colon-delimited list.
Can you (or anyone else) please help me get a little further? Once again, feel free to login to my host account to see it first hand.
Thanks again!
Mark -
Hi all
We have been designing resource management system and want to provide flexible way to extend resource properties at runtime. So we are storing resource properties in a single table, e.g.
select * from _kv
ID K V
1 name Bob
1 age 30
1 gender male
2 name Susan
2 status married
convert to
+-----+-------+--------+----------+
| key | color | height | whatever |
+-----+-------+--------+----------+
| 1 | green | 15 | --- |
| 2 | --- | --- | lol |
+-----+-------+--------+----------+
example of dynamic pivot Dynamic SQL Pivoting &#8211; Stealing Anton&#8217;s Thunder</title> //<title>AMIS Technology Blog…
Is it possible to create interactive report with dynamic columns updated when _kv will be changed?
Is it possible to create add/edit dynamic form depends on key set if we add value type description?
Thanksmake sure you put some thought into your database design before you go too far.
There are many horror stories about EAV based schema designs. (which this design seems to be heading.)
Read up on them before you go too far.
-- back to being on topic --
AFAIK you can not do dynamic SELECT with an Interactive Report.
However, you can with a Basic Report. But, it is non-trivial. (ie it is difficult to do)
Basic Report can use a "function returning SELECT statement".
You will also need to name the columns based on a different function.
In order to 'synchronize' the column names with the SELECT statement, you will need a 3rd function that properly generates them.
This 3rd function MUST have an 'ORDER BY' clause.
Both the generateSELECT() function and the generateCOLUMN_NAMES() function will call that 3rd function.
From a code management standpoint, you will need to create a package that contains all three functions.
are you sure you want to go this route?
are you ready to go this route?
Again, think about your table designs.
MK -
i'm trying to get a report to pivot like in SQL (like this article, actually http://technology.amis.nl/blog/1207/dynamic-sql-pivoting-stealing-antons-thunder) but APEX (4.0) doesn't seem to like the PIVOT command.
i'm trying to get a report that looks like this:
Currency--Distinguisher--Total
USD--REAL--2500.00
USD--THEO--2250.00
EUR--REAL--750.00
EUR--THEO--1000.00
GBP--REAL--50.00
to look like this
Distinguisher--GBP--EUR--USD
REAL--50.00--750.00--2500.00
THEO--0.00--1000.00--2250.00
i'm also wondering if i can put a USD conversion column at the end that will sum the dynamic list after converting all the currencies to their daily USD values.
dynamic: new currencies could be added at any time without warning, i'd like those automatically added both to the pivoted table as well as the summed currency. my report is dynamic across several departments that all have different currency holdings.
many thanks.What it is doing is:
select
deptno,
rtrim (xmlagg (xmlelement (e, ename || ',')).extract ('//text()'), ',') enames
from
emp
group by
deptno;
We are selecting the deptno (grouping column) and trimming the returned value from an xml function call on the data column ename. we are treating the data in the column ename as an element of xml data and extracting it from the data stream and appending into a string, adding a , when we return a new element. Since we are grouping by deptno, we start a new group when the deptno changes..Thank you,
Tony Miller
Webster, TX
While it is true that technology waits for no man; stupidity will always stop to take on new passengers.
If this question is answered, please mark the thread as closed and assign points where earned.. -
Converting rows to columns using t-sql
Hi All,
I have a table with 3 columns, let say ID1 , ID2, Flag
My Source data looks like this..
ID1 ID2 Flag
1 1 0
1 2 0
1 3 0
2 7 0
2 8 1
2 9 0
4 5 0
Now My output should look like this..
ID1 Newcol1 NewFlag1 Newcol2 NewFlag2 Newcol3 NewFlag3
1 1 0
2 0 3
0
2 7 0
8 1 9
0
4 5 0
null null null null
Basically I want to convert rows to columns and to get above output I need t-SQL query.
Thanks in advance
RH
sqlYou can do it by this query:
declare @table table ( ID1 int, ID2 int, Flag int)
insert @table values ( 1,1,0 ),( 1,2,0 ),( 1,3,0 ),( 2,7,0 ),( 2,8,1 ),( 2,9,0 ),( 4,5,0 )
WITH cte1
AS ( SELECT Id1 ,
ROW_NUMBER() over (partition by ID1 order by ID1 ) as Sequence ,
ID2 ,
Flag
FROM @table
cte2
AS ( SELECT Id1 ,
ColumnTitle + LTRIM(RTRIM(STR(Sequence))) AS ColumnTitle ,
ColumnData
FROM cte1 UNPIVOT ( ColumnData FOR ColumnTitle IN ( [ID2], [Flag] ) ) AS UP
SELECT Id1 ,
[ID21] FirstID2 ,
[Flag1] FirstFlag ,
[ID22] SecondID2 ,
[Flag2] SecondFlag ,
[ID23] ThirdID2 ,
[Flag3] ThirdFlag
FROM cte2 PIVOT ( MAX(ColumnData) FOR ColumnTitle IN ( [ID21],
[Flag1],
[ID22],
[Flag2],
[ID23],
[Flag3] ) ) PV
If you want to know more detail, please visit my old article about this method:
T-SQL: PIVOT Ordered pair Columns
T-SQL e-book by TechNet Wiki Community
My Blog
My Articles -
Need Matrix Style Report...
I need to create a matrix style report. There is a template for matrix reports in Oracle Report Writer, but not in APEX. My report should have a list of countries going down and a list of species going across with data showing how many for each country, each species.
Example of report:
Species Pollack Whiting Tuna
Country
China 5 6 10
Chile 1 2 1
Japan 4 4 8
How do I build this?Is this in Oracle 11g?? If so, you could use the pivot function in your sql to build the output data..
http://technology.amis.nl/blog/1207/dynamic-sql-pivoting-stealing-antons-thunder
Also threads in APEX forum dealing with this:
How to create a matrix report
Thank you,
Tony Miller
Webster, TX
Maybe you are looking for
-
What is the best way to repeatedly load random commercials?
Hi Everyone, Any help with the above question would be useful. Here's my end goal: I want to display commercials on a screen at my wife's bakery. The script should load one commercial, play it, then unload it, randomly load another, and so on. I am
-
Add a value from the cloud or internet in a cell
How to add a value from the web, need to add the value of the conversion of € to $
-
Mirror your mac to TV with AppleTV
I'm looking for a way to mirror whats on my macbook pro on to my TV using AppleTV. I know that you can use airplay with different applications but was wondering if you can display your monitor.
-
How to make fields editable in Personal Profile Application(WDA)
Hi Experts, I am not able to make the passport field field editable in Personal Profile Application. The passport field is uneditable. How do we make it editable so that user can enter Identity No. Please help. Regards, Priti
-
Weblogic-application.xml
Is there a way I can get the contents of "application-param" element from weblogic-application.xml in a J2EE bean ? Are the contents of weblogic-application.xml bound to the JNDI tree? I am using WLS/WLI 8.1 SP2. Vishwa