With clause not working with union - oracle

My query result is a union of several queries. I am facing the below error when I use WITH clause within a union. Any ideas why?
select column1 from TABLE_A
union
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
ORA-32034: unsupported use of WITH clause
32034. 00000 - "unsupported use of WITH clause"
*Cause: Inproper use of WITH clause because one of the following two reasons
1. nesting of WITH clause within WITH clause not supported yet
2. For a set query, WITH clause can't be specified for a branch.
3. WITH clause can't sepecified within parentheses.
*Action: correct query and retry

Encapsulate your WITH statement in a dummy select.
select column1 from TABLE_A
union
select * from (
with abcd as (select * from TABLE_B)
select column2 from TABLE_A A, abcd
where abcd.m_reference = A.m_reference
)

Just define the CTE first, before the actual UNION query. Then use it as you would a regular table:
with abcd as (select * from TABLE_B)
select column1 from TABLE_A
union
select column2
from TABLE_A A
inner join abcd
on abcd.m_reference = A.m_reference
You can use multiple CTE as follows:
with cte1 AS (...),
cte2 AS (...)
select * from ...

Encapsulating it is the way to go if you have multiple WITHs; for example I just had to do this monstrosity to quickly pull in data from ID numbers from an Excel sheet
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800727'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800004'
)
UNION ALL
select * from (
with childvendor as (
select vendornumber, name From vendor where vendornumber = '0000800042'
)
select
v.vendornumber as parentvendor,
v.name as parentname,
cv.vendornumber as childvendor,
cv.name as childname
From
vendor v, childvendor cv
where
v.vendornumber = '0000800035'
)
And so on

Related

Oracle SQL -- Finding count of rows that match date maximum in table

I am trying to use a query to return the count from rows such that the date of the rows matches the maximum date for that column in the table.
Oracle SQL: version 11.2:
The following syntax would seem to be correct (to me), and it compiles and runs. However, instead of returning JUST the count for the maximum, it returns several counts more or less like the "HAIVNG" clause wasn't there.
Select ourDate, Count(1) as OUR_COUNT
from schema1.table1
group by ourDate
HAVING ourDate = max(ourDate) ;
How can this be fixed, please?
You can use:
SELECT MAX(ourDate) AS ourDate,
COUNT(*) KEEP (DENSE_RANK LAST ORDER BY ourDate) AS ourCount
FROM schema1.table1
or:
SELECT ourDate,
COUNT(*) AS our_count
FROM (
SELECT ourDate,
RANK() OVER (ORDER BY ourDate DESC) AS rnk
FROM schema1.table1
)
WHERE rnk = 1
GROUP BY ourDate
Which, for the sample data:
CREATE TABLE table1 (ourDate) AS
SELECT SYSDATE FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
SELECT SYSDATE - 1 FROM DUAL;
Both output:
OURDATE
OUR_COUNT
2022-06-28 13:35:01
5
db<>fiddle here
I don't know if I understand what you want. Try this:
Select x.ourDate, Count(1) as OUR_COUNT
from schema1.table1 x
where x.ourDate = (select max(y.ourDate) from schema1.table1 y)
group by x.ourDate
One option is to use a subquery which fetches maximum date:
select ourdate, count(*)
from table1
where ourdate = (select max(ourdate)
from table1)
group by ourdate;
Or, a more modern approach (if your database version supports it; 11g doesn't, though):
select ourdate, count(*)
from table1
group by ourdate
order by ourdate desc
fetch first 1 rows only;
You can use this SQL query:
select MAX(ourDate),COUNT(1) as OUR_COUNT
from schema1.table1
where ourDate = (select MAX(ourDate) from schema1.table1)
group by ourDate;

ORA-00979 Not a Group function error for query with User defined function in select statement

I have this query where a user defined function is added in the select and group by statement.
The inner select query without the WITH clause runs fine and doesn't give any error. But after adding WITH clause it gives the following error -
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action: Error at Line: 3 Column: 29
I need the WITH clause to return only a subset of the entire result set based on input ranges.
Query is as follows:
WITH INFO AS (
SELECT
GET_EVAULATED_VALUE(T.C_IMP, T.IMP) AS IMPORTANCE,
count(*) AS NO_OF_PC_AFFECTED
FROM TABLE_NAME T
WHERE T.ACNT_REL_ID = 16
GROUP BY
(GET_EVAULATED_VALUE(T.C_IMP, T.IMP))
ORDER BY IMPORTANCE desc
)
SELECT * FROM
(
SELECT ROWNUM AS RN,
(SELECT COUNT(*) FROM INFO) COUNTS,
IMPORTANCE
FROM INFO
)
WHERE RN > 0 AND RN <= 10;
I am not sure how to use CTE with group by on user defined function. But I realized that I can rewrite the query to remove sub-query and CTE and make it simpler as following (and it works):
select * from (
select a.*, ROWNUM rnum from
(SELECT
count(*) over() as COUNTS,
GET_EVAULATED_VALUE(T.C_IMP, T.IMP) AS IMPORTANCE,
count(*) AS NO_OF_PC_AFFECTED
FROM TABLE_NAME T
WHERE T.ACNT_RELATION_ID = 16
GROUP BY
(GET_EVAULATED_VALUE(T.C_IMP, T.IMP))
ORDER BY importance desc) a
where ROWNUM <= 10 )
where rnum >= 0;
Same issue here, I created a table "TABLE_CTE" instead of using a CTE and it worked.
CREATE TABLE TABLE_CTE
AS
SELECT
USER_DEFINED_FUNCTION(date_1),
COUNT(*)
FROM
TABLE_NAME
GROUP BY
USER_DEFINED_FUNCTION(date_1)
;
SELECT * FROM TABLE_CTE

merge 2 Oracle queries into one with some generic data specified with null

Can I write one Oracle query that can do something like that?
if code is XXX, then return V1,V2
if code is not XXX, then return those values whose code = null, i.e. V3, V4
Table1
code value
---- -----
XXX V1
XXX V2
null V3
null V4
I need to write something like that:
select * from Table1 where code = 'XXX'
if no rows return, run the follow query
select * from Table1 where code is null
I'm not sure that I completely follow what you are looking for. You could implement your bullet points with something like
select *
from table1 t1
where t1.code = 'XXX'
union all
select *
from table1 t1_2
where t1_2.code is null
and not exists( select 1
from table1 t1_3
where t1_3.code = 'XXX' )
I used dbfiddle.uk for testing only but I think this would work. Just remove the "with table1 as" clause as it is used for building up the data for testing.
with table1 as
(
select 'XXX' as code, 'V1' as value from dual
union
select 'XXX' as code, 'V2' as value from dual
union
select null as code, 'V3' as value from dual
union
select null as code, 'V4' as value from dual
)
select *
from table1
where nvl(code, '!!!') = 'XXX'
union
select *
from table1
where code is null
and not exists(select 1 from table1 where code='XXX')
with q as
(select code, value from table1 where code = 'XXX')
select *
from q
union all
select code, value
from table1
where code is null and not exists (select 1 from q)

how to get exact string value from delimited column value match in oracle database

I have 2 tables
Table 1:
#######
ID Location
1 India
2 Australia
Table 2:
############
Name Locations
test1 India|North America
test2 Indiana|Australia
I used the below query to get the Name from table 2 if it contains Location in Locations of table 2.
select Name
from table2 t2 inner join table1 t1
on instr(t1.Location,t2.Locations,length(t1.Location)) >= 1;
But when executed it still gives me results for Indiana as well whereas it should just return me result for location India alone.
I tried using contains in query too, but contains takes second parameter as string but not as column name.
Is there any other approach on this?
regexps always help in such cases
with
table1 (id, location) as (
select 1, 'India' from dual union
select 2, 'Australia' from dual
),
table2 (name, locations) as (
select 'test1', 'India|North America' from dual union
select 'test2', 'Indiana|Australia' from dual
)
select *
from table2 join table1 on
regexp_like (locations, '(^|\|)' || location || '(\||$)')
Try to look up location with delimiter, like this:
select Name from table2 t2
inner join table1 t1 on instr(t2.Locations,t1.Location||'|') >= 1

Oracle update statement with analytics is failing

The Table_B contains duplicate records as seen below. What I am trying to do is lookup Table_A using Table_B.SERIAL_NUM and update Table_A .COVERAGE_END coloumn with the most recent Date value in COVERAGE_TO coloumn in Table_B.
Table_B
SERIAL_NUM ,COVERAGE_FROM ,COVERAGE_TO
123456 ,26/12/2014 ,13/12/2015
123456 ,14/12/2015 ,13/12/2016
23456 ,18/12/2014 ,13/12/2015
23456 ,14/12/2015 ,13/12/2016
Following is the update statement I am using.
update Table_A J
set ( J.COVERAGE_END_DATE)
=(select COVERAGE_TO from
(
select SERIAL_NUM, COVERAGE_TO, row_number() over(partition by SERIAL_NUM order by COVERAGE_TO desc) as rn from TABLE_B B
)where rn = 1
)
where exists
(
select * from TABLE_B Q where Q.SERIAL_NUM = J.SERIAL_NUMBER
)
;
However I get the following error
ORA-01427: single-row subquery returns more than one row
Can Some one please help me with this Query?
You have to compare J's SERIAL_NUMBER with B's to get the only proper value.
where rn = 1 and J.SERIAL_NUMBER = SERIAL_NUM
If not, subquery will return max values for every SERIAL_NUM.
I'm not sure why partitioning is needed here.
Would a simple MAX() not produce the needed result?
update table_a
set coverage_end_date = (
select max(coverage_to)
from table_b b inner join table_a a on b.serial_num = a.serial_num
)
;

Resources