如何将以下查询从 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
我正在将我的应用程序数据库从 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