如何将以下查询从 Oracle 转换为具有连接方式的 Postgres?

How to convert below query from Oracle to Postgres having connect by?

我正在将我的应用程序数据库从 oracle 转换为 postgres。我被困在一个按语法连接的函数上。下面是 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;

当我将此查询转换为 postgres 时,有一些更改,例如 Ref_Cur 到 refcursor 和 NVL 到 Coalesce 函数。我仍然无法通过语法解析连接。有人建议使用 CTE,但我无法获得。有帮助吗?

编辑 对于下面的随机 googlers,是我上述问题的答案。特别感谢 MTO.

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 = p_Billing_Month) data

Right Outer Join (Select 1 as Id union All
                  Select 2 as Id union All
                  Select 3 as Id union All
                  Select 4 as Id) all_value 
            On data.Amount_Sort = all_value.Id
GROUP BY all_value.Id
ORDER BY AVG(all_value.Id);

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

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,', ',')

收件人:

SELECT 1 AS id FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL UNION ALL
SELECT 4 FROM DUAL

转换为 PostgreSQL 应该更简单。

ID 的 "generation" 在 Postgres 中可以简化。

要么使用 values() 子句:

Right Outer Join ( values (1,2,3,4) ) as all_value(id) On data.Amount_Sort = all_value.Id

或者,如果这些总是 连续 个数字,请使用 generate_series():

Right Outer Join generate_series(1,4) as all_value(id) On data.Amount_Sort = all_value.Id