Sql 如何将下面的查询从Oracle转换为具有connect by的Postgres?

Sql 如何将下面的查询从Oracle转换为具有connect by的Postgres?,sql,database-migration,postgresql-9.4,Sql,Database Migration,Postgresql 9.4,我正在将我的应用程序数据库从oracle转换为postgres。我被一个具有connect by语法的函数卡住了。下面是Oracle查询 PROCEDURE Get_Report_Data(parm_Billing_Month VARCHAR2, OUT Ref_Cur) IS BEGIN OPEN p_Data FOR SELECT CASE WHEN Id = 1 THEN 'Amount < 10000' WHE

我正在将我的应用程序数据库从oracle转换为postgres。我被一个具有connect by语法的函数卡住了。下面是Oracle查询

PROCEDURE Get_Report_Data(parm_Billing_Month VARCHAR2, OUT Ref_Cur) IS
BEGIN
OPEN p_Data FOR
  SELECT CASE
           WHEN Id = 1 THEN
            'Amount < 10000'
           WHEN Id = 2 THEN
            '10000-15000'
           WHEN Id = 3 THEN
            '15000-20000'
           ELSE
            'Amount > 20000'
         END "Range",
         SUM(Nvl(N1, 0)) N1,
         SUM(Nvl(N2, 0)) N2,
         SUM(Nvl(C1, 0)) C1,
         SUM(Nvl(C2, 0)) C2,
         SUM(Nvl(C3, 0)) C3,
         SUM(Nvl(S1, 0)) S1,
         SUM(Nvl(S2, 0)) S2,
         COUNT(Site_Id) "No of Sites"
    FROM (SELECT CASE
                   WHEN Nvl(Ed.Actual_Bill, 0) < 10000 THEN
                    1
                   WHEN Ed.Actual_Bill < 15000 THEN
                    2
                   WHEN Ed.Actual_Bill < 20000 THEN
                    3
                   ELSE
                    4
                 END Amount_Sort,
                 Decode(Er.Region_Id, 1, 1, 0) N1,
                 Decode(Er.Region_Id, 2, 1, 0) N2,
                 Decode(Er.Region_Id, 3, 1, 0) C1,
                 Decode(Er.Region_Id, 4, 1, 0) C2,
                 Decode(Er.Region_Id, 5, 1, 0) C3,
                 Decode(Er.Region_Id, 6, 1, 0) S1,
                 Decode(Er.Region_Id, 7, 1, 0) S2,
                 Ed.Site_Id
            FROM Tbl_Details   Ed,
                 Tbl_Site      Es,
                 Tbl_Region    Er,
                 Tbl_Subregion Esr
           WHERE Ed.Site_Id = Es.Site_Id
             AND Es.Subregion_Id = Esr.Subregion_Id
             AND Esr.Region_Id = Er.Region_Id
             AND Ed.Billing_Month_f = parm_Billing_Month) Data,
         (SELECT Regexp_Substr('1,2,3,4,', '[^,]+', 1, Rownum) Id
            FROM Dual
          CONNECT BY Rownum <= Length('1,2,3,4,') -
                     Length(REPLACE('1,2,3,4,', ','))) All_Value
   WHERE Data.Amount_Sort(+) = All_Value.Id
   GROUP BY All_Value.Id
   ORDER BY AVG(All_Value.Id);
END;

由于分层查询似乎使用的是静态字符串,因此可以将其转换为:

SELECT Regexp_Substr('1,2,3,4,', '[^,]+', 1, Rownum) Id
FROM Dual
CONNECT BY Rownum <= Length('1,2,3,4,') - Length(REPLACE('1,2,3,4,', ',')
转换成PostgreSQL应该更简单。

在Postgres中可以简化ID的“生成”

使用
values()
子句:

Right Outer Join ( values (1,2,3,4) ) as all_value(id) On data.Amount_Sort = all_value.Id
或者,如果这些始终是连续的数字,请使用
生成\u series()


非常感谢。非常好而且简单的回答。事实上,在我接下来的报告中,有一个复杂的查询返回一些数字。所以为了简单起见,我需要MTO提供的语法。但是非常感谢您提供的信息。@Meta Coder:我个人认为
values()
子句比复杂的
select更易于阅读和维护。。union all select…
syntaxI完全同意您的意见。即使在我的报告中,我也使用了values(1,2,3,4)子句,但在接下来的报告中,我需要一个具有多个联接的复杂查询。这让我对Connect by的语法感到困惑。干杯
SELECT 1 AS id FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL UNION ALL
SELECT 4 FROM DUAL
Right Outer Join ( values (1,2,3,4) ) as all_value(id) On data.Amount_Sort = all_value.Id
Right Outer Join generate_series(1,4) as all_value(id) On data.Amount_Sort = all_value.Id