I want to get records from two table that are linked with fk. This fk can be null and the child table must have a filter.
I explain it with simple example.
Table Poet
IdPoet Number(5)
NameVarchar2(250)
Table Poem
IdPoem Number(5)
IdPoet Number(5) FK
Language Number(1)
Text Varchar2(2000)
The FK is relationship Poet and Poem
Poet-1————–N0—PoemPoem.IdPoet can be null.
I need to get all records from Poet that don’t have poems, and poets that have poems with language=1 or language=2. Language 1 is more restrictive that 2. This mean that if there are a Poet that have 2 poems (one writes on language 1 and other write on language 2) must show only record with language 1.
SELECT *
FROM POET, POEM
WHERE POET.IDPOET = POEM.IDPOET(+)
AND
(
(POEM.LANGUAGE IS NOT NULL AND POE.LANGUAGE = 1) OR
(POEM.LANGUAGE IS NOT NULL AND POE.LANGUAGE = 2) OR
(POEM.LANGUAGE IS = 1) OR
(POEM.LANGUAGE IS = 2)
)
This select shows Poets that don’t have poems, that have 1 poem on language 1 or that have 1 poem on language 2. The problem is when poem have 2 poems, one on language 1 and other on language 2, then show 2 records, and i want to show only record with poem on language 1 because is more restrictive than 2.
You can do this pretty easily using Oracle’s ROW_NUMBER() analytic function:
Note that if there are multiple poems in language 1 for a single poet, it’ll just pick whichever one is returned first from the database. You could add another field to the
ORDER BYin the partition clause to sort by poem name, etc. first if you wanted.SQL Fiddle
Edit: Also, if you want the same behavior that alzaimar proposed (i.e., all poems from language 1 are shown), you can use the
DENSE_RANK()function instead ofROW_NUMBER().