Sql 如何将下面的查询从Oracle转换为具有connect by的Postgres?
我正在将我的应用程序数据库从oracle转换为postgres。我被一个具有connect by语法的函数卡住了。下面是Oracle查询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
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