I have been trying out a code using pivot
to get a certain view from a table .
create table temp
(
date datetime,
category varchar(3),
amount money
)
insert into temp values ('1/1/2012', 'ABC', 1000.00)
insert into temp values ('2/1/2012', 'DEF', 500.00)
insert into temp values ('2/1/2012', 'GHI', 800.00)
insert into temp values ('2/10/2012', 'DEF', 700.00)
insert into temp values ('3/1/2012', 'ABC', 1100.00)
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.category)
FROM temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT date, ' + @cols + ' from
(
select date
, amount
, category
from temp
) x
pivot
(
max(amount)
for category in (' + @cols + ')
) p '
execute(@query)
drop table temp
I get an error in the declare
statement and also pivot
is not being recognised as a keyword by dbviz SQL commander
I even removed the @
and tried to run it , I'm not able to execute successfuly
I'm using Oracle Database 11g ( oracle JDBC driver )
If you are trying to run this code from SQLPlus or SQLcl, you can use code below to generate the same information in Oracle.
In Oracle 19, Oracle introduce the ability to do LISTAGG(DISTINCT <value>)
which removes the need to do a subquery to remove any duplicates.
CREATE TABLE temp
(
date_val DATE,
category VARCHAR (3),
amount NUMBER
);
INSERT INTO temp
VALUES (DATE '2012-01-01', 'ABC', 1000.00);
INSERT INTO temp
VALUES (DATE '2012-02-01', 'DEF', 500.00);
INSERT INTO temp
VALUES (DATE '2012-02-01', 'GHI', 800.00);
INSERT INTO temp
VALUES (DATE '2012-02-10', 'DEF', 700.00);
INSERT INTO temp
VALUES (DATE '2012-03-01', 'ABC', 1100.00);
column category_list NEW_VALUE categories
SELECT '''' || LISTAGG (DISTINCT category, ''',''') WITHIN GROUP (ORDER BY category) || '''' AS category_list
FROM temp;
SELECT *
FROM (SELECT date_val, amount, category FROM temp) x
PIVOT (MAX (amount) FOR category IN (&categories)) p;
DROP TABLE temp;
CREATE TABLE temp
(
date_val DATE,
category VARCHAR (3),
amount NUMBER
);
INSERT INTO temp
VALUES (DATE '2012-01-01', 'ABC', 1000.00);
INSERT INTO temp
VALUES (DATE '2012-02-01', 'DEF', 500.00);
INSERT INTO temp
VALUES (DATE '2012-02-01', 'GHI', 800.00);
INSERT INTO temp
VALUES (DATE '2012-02-10', 'DEF', 700.00);
INSERT INTO temp
VALUES (DATE '2012-03-01', 'ABC', 1100.00);
column category_list NEW_VALUE categories
SELECT '''' || LISTAGG (category, ''',''') WITHIN GROUP (ORDER BY category) || '''' AS category_list
FROM (SELECT DISTINCT category
FROM temp);
SELECT *
FROM (SELECT date_val, amount, category FROM temp) x
PIVOT (MAX (amount) FOR category IN (&categories)) p;
DROP TABLE temp;
SQL> @test_tsql_conversion.sql
Table TEMP created.
1 row inserted.
1 row inserted.
1 row inserted.
1 row inserted.
1 row inserted.
CATEGORY_LIST
____________________
'ABC','DEF','GHI'
old:SELECT *
FROM (SELECT date_val, amount, category FROM temp) x
PIVOT (MAX (amount) FOR category IN (&categories)) p
new:SELECT *
FROM (SELECT date_val, amount, category FROM temp) x
PIVOT (MAX (amount) FOR category IN ('ABC','DEF','GHI')) p
DATE_VAL 'ABC' 'DEF' 'GHI'
____________ ________ ________ ________
01-FEB-12 500 800
10-FEB-12 700
01-JAN-12 1000
01-MAR-12 1100
Table TEMP dropped.
Building on EJ Egyed's answer, here is a PL/SQL version:
declare
cols long;
query long;
results sys_refcursor;
begin
select '''' || listagg(category||''' as "'||upper(category)||'"', ', ''') within group (order by category)
into cols
from (select distinct category from temp);
query :=
'select * from
( select dt, amount, category
from temp ) x
pivot
( max(amount) for category in ('||cols||') ) p';
open results for query;
dbms_sql.return_result(results);
end;
The solution will vary depending on how you want to execute the code. dbms_sql.return_result
will pass the result set to a 12c or later client such as SQL*Plus or SQL Developer, but might not work with third party tools such as DbVisualizer or Tableau. SQL*Plus is Oracle's basic command line tool used mostly for administration and deployment scripts, but not really suited for end user reporting. SQL Developer is a programmer's IDE, which a business analyst might use, but again it's not really for general end users.
The most generic approach might be to write this as a procedure that returns a refcursor, which could then be processed by an application written in Java, C# etc.
A procedure version would look like this:
create or replace procedure pivot_categories
( out_results out sys_refcursor )
as
cols long;
query long;
begin
select '''' || listagg(category||''' as "'||upper(category)||'"', ', ''') within group (order by category)
into cols
from (select distinct category from temp);
query :=
'select * from
( select dt, amount, category
from temp ) x
pivot
( max(amount) for category in ('||cols||') ) p';
open out_results for query;
end pivot_categories;
here is what you need:
create table temp
(
date timestamp(3),
category varchar2(3),
amount number
);
insert into temp values ('1/1/2012', 'ABC', 1000.00)
insert into temp values ('2/1/2012', 'DEF', 500.00)
insert into temp values ('2/1/2012', 'GHI', 800.00)
insert into temp values ('2/10/2012', 'DEF', 700.00)
insert into temp values ('3/1/2012', 'ABC', 1100.00)
v_cols NVARCHAR(MAX);
v_query NVARCHAR(MAX);
SELECT STUFF((SELECT distinct ',' || QUOTENAME(c.category)
FROM temp c
FOR INTO v_cols FROM dual XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
v_query := 'SELECT date, ' || v_cols || ' from
(
select date
, amount
, category
from temp
) x
pivot
(
max(amount)
for category in (' || v_cols || ')
) p '
execute immediate v_query
drop table temp
also there is an online sql convert tool : http://www.sqlines.com/online
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.