PostgreSQL Recursive Function Not working - sql

I have a requirement to get the hierarchical structure for the employees.
Below is the current recursive function I am using:
WITH RECURSIVE resource_tbl AS (
select pers_id,pers_full_nm,mgr_id,mgr_full_nm, 1 as level from resource
UNION ALL
select t.pers_id,t.pers_full_nm,t.mgr_id,t.mgr_full_nm, c.level+1 from resource_tbl c
INNER JOIN resource t ON t.mgr_id = c.pers_id
)
SELECT *
FROM resource_tbl
ORDER BY level;
When I run this query I get the below error:
ERROR: RECURSIVE option in WITH clause is not supported SQL state:
0AM00
Does Anyone had this Problem before? The Postgres SQL version is 8.2.
If Version is a Problem then how can I implement in the Current PostgreSQL environment we had?

Related

Cannot use a CTE in a scalar subquery in Db2

I'm trying to use a CTE in a DB2 LUW v11.5.4.0 scalar subquery, but this doesn't work:
SELECT 1
FROM SYSIBM.dual
WHERE 1 IN (
WITH t (x) AS (SELECT 1 FROM SYSIBM.dual)
SELECT * FROM t
);
I'm getting this error:
SQL Error [42601]: An unexpected token "AS" was found following "1 IN (
WITH t (x)". Expected tokens may include: "JOIN".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.26.14
Can this be done? Is there a workaround?
(This is similar but not the same as this question, which is about derived tables, not scalar subqueries. Derived tables support CTE in version 11.5.4.0)
It seems that in version 11.5.4.0, it's possible to use CTEs in derived tables, so the query can be emulated as follows:
SELECT 1
FROM SYSIBM.dual
WHERE 1 IN (
SELECT *
FROM (
WITH t (x) AS (SELECT 1 FROM SYSIBM.dual)
SELECT * FROM t
) t
);
However, this workaround also doesn't work in older versions of Db2, e.g. in version v11.1.4.4 as can be seen in this dbfiddle or in this question. The workaround in those versions will be to push the CTE to the top level of the query:
WITH t (x) AS (SELECT 1 FROM SYSIBM.dual)
SELECT 1
FROM SYSIBM.dual
WHERE 1 IN (
SELECT * FROM t
);
Side note
HSQLDB seems to suffer from a similar limitation / bug, see https://sourceforge.net/p/hsqldb/bugs/1617.

recursive query with select * raises ORA-01789

This is a minimized version of complex recursive query. The query works when columns in recursive member (second part of union all) of recursive CTE are listed explicitly:
with t (c,p) as (
select 2,1 from dual
), rec (c,p) as (
select c,p from t
union all
select t.c,t.p from rec join t on rec.c = t.p
)
select * from rec
I don't get why error ORA-01789: query block has incorrect number of result columns is raised when specified t.* instead.
with t (c,p) as (
select 2,1 from dual
), rec (c,p) as (
select c,p from t
union all
select t.* from rec join t on rec.c = t.p
)
select * from rec
Why t.* is not equivalent to t.c,t.p here? Could you please point me to documentation for any reasoning?
UPDATE: reproducible on 11g and 18 (dbfiddle).
I finally asked on AskTom forum and according to response from Oracle expert Connor McDonald, this behavior is in compliance with documentation, namely the sentence The number of column aliases following WITH query_name and the number of columns in the SELECT lists of the anchor and recursive query blocks must be the same which can be found in this paragraph.
The point is, the expansion of star expression is done after checking whether the numbers of columns are same. Hence one must list columns explicitly, shortening to star is not possible.
Seems like there could be some kind of bug to me. I modified the query slightly just to test various cases and am now able to reproduce an ORA-00600 error in my Oracle 19.6.0.0.0 database! Running the problematic query on apex.oracle.com or on livesql.oracle.com (which is running 19.8.0.0.0) also results in errors. Reporting it to Oracle now!

Hive: less than operator error in subquery

I want the latest records from HIVE table using the following query-
WITH lot as (select *
from to_burn_in as a where a.rel_lot='${Rel_Lot}')
select a.* from lot AS a
where not exists (select 1 from lot as b
where a.Rel_Lot=b.Rel_Lot and a.SerialNum=b.SerialNum and a.Test_Stage=b.Test_Stage
and cast(a.test_datetime as TIMESTAMP) < cast(b.Test_Datetime as TIMESTAMP))
order by a.SerialNum
this query is throwing a error as
Error while compiling statement: FAILED: SemanticException line 0:undefined:-1 Unsupported SubQuery Expression 'Test_Datetime': SubQuery expression refers to both Parent and SubQuery expressions and is not a valid join condition.
I have tried running with equal operator in place of the less than operator in subquery and it is running fine. I read the HIVE documentation as given in
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SubQueries
and couldn't figure out why it is throwing a error as 'where' subquery is supported.
What might be the problem here?
EXISTS works the same as a join actually. Not equality join conditions are not supported in Hive prior Hive 2.2.0 (see HIVE-15211, HIVE-15251)
It seems you are trying to get records having latest timestamp per Rel_Lot,SerialNum,Test_Stage. Your query can be rewritten using dense_rank() or rank() function:
WITH lot as (select *
from to_burn_in as a where a.rel_lot='${Rel_Lot}'
)
select * from
(
select a.*,
dense_rank() over(partition by Rel_Lot,SerialNum,Test_Stage order by cast(a.test_datetime as TIMESTAMP) desc) as rnk
from lot AS a
)s
where rnk=1
order by s.SerialNum

find group by clause error programmatically

We are going to update our database from 10g to 12c. Before doing so we need to revisit our SQLs, and as a part of this we need to check the following behavior of GROUP BY
case 1:
SELECT abcd_pk,
COUNT(abcd_code),
ABCD_COUNT
FROM
(SELECT abcd_pk,
abcd_code,
(SELECT COUNT(abcd_code) FROM ABCD_TABLE
) "ABCD_COUNT"
FROM ABCD_TABLE
)
GROUP BY abcd_pk, ABCD_COUNT ;
WORKS IN 10G
WORKS IN 12C
case 2:
SELECT abcd_pk,
COUNT(abcd_code),
ABCD_COUNT
FROM
(SELECT abcd_pk,
abcd_code,
(SELECT COUNT(abcd_code) FROM ABCD_TABLE
) "ABCD_COUNT"
FROM ABCD_TABLE
)
GROUP BY abcd_pk ;
WORKS IN 10G
DOES NOT WORK IN 12C (ORA-00979: not a GROUP BY expression 00979. 00000 - "not a GROUP BY expression")
Our code may contains case2 like SQL which is not appropriate. So we need to identify those SQLs. I already prepared a list of SQLs contains GROUP BY used in our project (.java files/procedure/function/views etc.).
Requirement is find the problem in GROUP BY using the following process:
Check the SQLs in the list one by one.
Find an alternate way to check the list of SQLs programmatically.
Option 1 requires massive work load, effort and time, but I think option 2 is not possible.
Is there any suggestion how to proceed?
One possible workaround which might work would be to place the count subquery into an aggregate function, e.g. AVG():
SELECT abcd_pk,
COUNT(abcd_code),
AVG(ABCD_COUNT) -- use an aggregate to not offend Oracle
FROM
(
SELECT abcd_pk,
abcd_code,
(SELECT COUNT(abcd_code) FROM ABCD_TABLE) "ABCD_COUNT"
FROM ABCD_TABLE
)
GROUP BY abcd_pk;
If this fixes the problem, then it means that Oracle's treatment of subqueries resulting in constants has changed between 10G and 12C.

How to make pl/sql code to Ansi-Sql?

My question may be not challenging for sql expert. i want to rewrite my sql as a ansi-sql. How can i change below sql to ansi-sql in Oracle?
select *
from TEST r
start with r.childid=#CHILDID
connect by prior r.PARENTID=r.childid and r.recordstatus=1
The ANSI SQL equivalent would be a recursive common table expression:
with recursive tree as (
select *
from test
where childid = .... --<< this is the START WITH part
union all
select child.*
from test child
join tree parent ON child.parentid = parent.childid and child.recordstatus = 1 --<< this is the CONNECT BY part
)
select *
from tree
I'm not 100% if you also want to apply the recordstatus = 1 condition to the recursion start.
Oracle doesn't comply with the standard here, and you are not allowed to use the recursive keyword.
So you need to remove recursive from the query above (the same is true for SQL Server)
More details about recursive common table expressions (called "subquery factoring" in Oracle) can be found in the manual:
https://docs.oracle.com/database/121/SQLRF/statements_10002.htm#SQLRF55268