微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将SQL Server T-SQL转换为SQL Oracle 19c及更高版本早于Oracle 19c 这两个脚本的结果

如何解决将SQL Server T-SQL转换为SQL Oracle 19c及更高版本早于Oracle 19c 这两个脚本的结果

我一直在尝试使用pivot从表中获取特定视图的代码

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 举报,一经查实,本站将立刻删除。