簡體   English   中英

將 SQL Server T-SQL 轉換為 SQL

[英]Convert SQL Server T-SQL to SQL

我一直在嘗試使用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', '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

我在declare語句中遇到錯誤,而且 dbviz SQL 指揮官也沒有將pivot識別為關鍵字

我什至刪除了@並嘗試運行它,但我無法成功執行

我正在使用 Oracle 數據庫 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', '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;

早於 Oracle 19c

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.

基於 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, amount, 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,業務分析師可能會使用它,但它也不是真正適用於一般最終用戶。

最通用的方法可能是將其編寫為返回引用的過程,然后可以由用 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)||'"', ', ''') 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;

這是你需要的:

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

還有一個在線 sql 轉換工具: http : //www.sqlines.com/online

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM