What is the equivalent PostgreSQL syntax to Oracle's CONNECT BY ... START WITH?
Use a RECURSIVE CTE
in Postgres:
WITH RECURSIVE cte AS (
SELECT key, value, 1 AS level
FROM taxonomy
WHERE key = 0
UNION ALL
SELECT t.key, t.value, c.level + 1
FROM cte c
JOIN taxonomy t ON t.taxHier = c.key
)
SELECT value
FROM cte
ORDER BY level;
Details and links to documentation in my previous answer:
- Does PostgreSQL have a pseudo-column like "LEVEL" in Oracle?
Convert oracle Sql to postgresql with CONNECT BY level
Postgres has a handy function called generate_series()
, which makes this kind of task easy:
select dt::date, rn
from generate_series('2019-01-01'::date, '2019-01-09'::date, '1 day')
with ordinality as d(dt, rn)
I don't see the point for the obsfucated logic in the connect by
clause of the Oracle query; the scalar subquery always evaluates as 9
.
Demo on DB Fiddlde:
dt | rn
:--------- | -:
2019-01-01 | 1
2019-01-02 | 2
2019-01-03 | 3
2019-01-04 | 4
2019-01-05 | 5
2019-01-06 | 6
2019-01-07 | 7
2019-01-08 | 8
2019-01-09 | 9
ORACLE connect by to POSTGRESQL conversion
Not sure what the group by nbr
is supposed to achieve - as far as I can tell this serves no purpose.
The convoluted connect by level
in Oracle can be replaced with a simple generate_series()
in Postgres.
So the following will generate 11 timestamp values from 2021-08-11 01:30:00
to 2021-08-11 06:30:00
:
select g.dt
from generate_series(timestamp '2021-08-11 01:30:00',
timestamp '2021-08-11 06:30:00',
interval '30 minute') as g(dt)
This can then be aggregated back into a string using string_agg()
select string_agg(to_char(dt, 'dd/mm/yyyy hh24:mi:ss'), ' '), 10 as nbr
from generate_series(timestamp '2021-08-11 01:30:00',
timestamp '2021-08-11 06:30:00',
interval '30 minute') as g(dt)
If you need the number of rows generated, you can use the with ordinality
clause to get that:
select string_agg(to_char(dt, 'dd/mm/yyyy hh24:mi:ss'), ' '), max(idx) as nbr
from generate_series(timestamp '2021-08-11 01:30:00',
timestamp '2021-08-11 06:30:00',
interval '30 minute') with ordinality as g(dt,idx)
Connect by level in Postgres on a sequence
The direct translation of that query is to use generate_series()
and nextval()
select nextval('id_seq')
from generate_series(1,3);
This will advance the sequence three times.
If however the goal is to set a specific value for an existing sequence (which requires such a hack in Oracle), just use setval()
:
select setval('id_seq', 3);
SYS_CONNECT_BY_PATH and START WITH/CONNECT BY PostgreSQL Equivalent
Use a recursive common table expression:
with recursive tree as (
select wtn,
resp_tcsi as tcsi_codes
from data
where rn = 1 -- this is the "start with" part
union all
select ch.wtn,
p.tcsi_codes||','||ch.resp_tcsi
from data as ch
join tree p
on ch.rn -1 = p.rn -- this is the "connect by" part
and ch.wtn = p.wtn
)
select *
from tree;
oracle sql to postgresql level query
select
case when date_part('month',current_date) >= 4 then
concat(date_part('year', current_date), '-', date_part('year',current_date)+1)
else
concat(date_part('year', current_date)-1, '-', date_part('year',current_date))
end FY
, lpad(date_part('month',d)::varchar,2,'0') MNTH
from (select DATE '2008-01-01' + (interval '1' month * generate_series(0,11)) d ) y
current_date
(instead of sysdate)+ Interval 'n Month'
(instead of add_months)generate series
(instead of connect by )date_part('month',...
to get the month number (instead of to_char(...,'MM') )concat()
for concatenations (looks after type conversions too)
sample result:
FY MNTH
1 2017-2018 01
2 2017-2018 02
3 2017-2018 03
4 2017-2018 04
5 2017-2018 05
6 2017-2018 06
7 2017-2018 07
8 2017-2018 08
9 2017-2018 09
10 2017-2018 10
11 2017-2018 11
12 2017-2018 12
Related Topics
How to Write a Constraint Concerning a Max Number of Rows in Postgresql
How to Edit a Table in Order to Enable Cascade Delete
Should I Use SQL_Variant Data Type
Sqlite Equivalent of Row_Number() Over (Partition by ...)
Why Are Logical Reads for Windowed Aggregate Functions So High
Differencebetween 'Yyyy' and 'Rrrr' in Oracle SQL
Oracle Insert If Row Does Not Exist
Retrieve Inserted Row Id in SQL
Transform and Pivot in Access 2013 SQL
MySQL Full Text Search for Words with Three or Less Letters
T-SQL Trim &Nbsp (And Other Non-Alphanumeric Characters)
T-SQL - Aliasing Using "=" Versus "As"
How to Convert from Varbinary to Char/Varchar in MySQL
Finding Rows That Don't Contain Numeric Data in Oracle
Array in In() Clause Oracle Plsql
Built-In Function to Capitalise the First Letter of Each Word