如何解决将SQL Server T-SQL转换为SQL Oracle 19c及更高版本早于Oracle 19c 这两个脚本的结果
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',700.00)
insert into temp values ('3/1/2012',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,'')
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
declare
语句中出现错误,并且dbviz sql Commander无法将pivot
识别为关键字
我什至删除了@
并尝试运行它,我无法成功执行
我正在使用Oracle Database 11g(oracle JDBC驱动程序)
解决方法
如果您试图从SQLPlus或SQLcl运行此代码,则可以使用下面的代码在Oracle中生成相同的信息。
Oracle 19c及更高版本
在Oracle 19中,Oracle引入了执行LISTAGG(DISTINCT <value>)
的功能,从而无需执行子查询来删除所有重复项。
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',700.00);
INSERT INTO temp
VALUES (DATE '2012-03-01',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;
早于Oracle 19c
CREATE TABLE temp
(
date_val DATE,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,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','GHI'
old:SELECT *
FROM (SELECT date_val,category FROM temp) x
PIVOT (MAX (amount) FOR category IN (&categories)) p
new:SELECT *
FROM (SELECT date_val,category FROM temp) x
PIVOT (MAX (amount) FOR category IN ('ABC','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.
,
基于EJ Egyed的答案,这是PL / SQL版本:
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,category
from temp ) x
pivot
( max(amount) for category in ('||cols||') ) p';
open results for query;
dbms_sql.return_result(results);
end;
解决方案将取决于您要如何执行代码。 dbms_sql.return_result
会将结果集传递给12c或更高版本的客户端(例如SQL * Plus或SQL Developer),但可能无法与第三方工具(例如DbVisualizer或Tableau)一起使用。 SQL * Plus是Oracle的基本命令行工具,主要用于管理和部署脚本,但并不真正适合最终用户报告。 SQL Developer是业务分析师可能会使用的程序员的IDE,但同样,它并不是真正面向一般最终用户的。
最通用的方法可能是将其编写为返回refcursor的过程,然后可以用Java,C#等编写的应用程序对其进行处理。
过程版本如下:
create or replace procedure pivot_categories
( out_results out sys_refcursor )
as
cols long;
query long;
begin
select '''' || listagg(category||''' as "'||upper(category)||'"',category
from temp ) x
pivot
( max(amount) for category in ('||cols||') ) p';
open out_results for query;
end pivot_categories;
,
这是您需要的:
create table temp
(
date timestamp(3),category varchar2(3),amount number
);
insert into temp values ('1/1/2012',1000.00)
insert into temp values ('2/1/2012',500.00)
insert into temp values ('2/1/2012',800.00)
insert into temp values ('2/10/2012',700.00)
insert into temp values ('3/1/2012',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,'')
v_query := 'SELECT date,' || v_cols || ' from
(
select date,category
from temp
) x
pivot
(
max(amount)
for category in (' || v_cols || ')
) p '
execute immediate v_query
drop table temp
还有一个在线SQL转换工具:http://www.sqlines.com/online
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。