我想从两个与fk链接的表中获取记录。此fk可以为null,子表必须具有过滤器。 我用简单的例子来解释它。
Table Poet
IdPoet Number(5)
NameVarchar2(250)
Table Poem
IdPoem Number(5)
IdPoet Number(5) FK
Language Number(1)
Text Varchar2(2000)
FK是Poet和Poem的关系 诗人-1 -------------- N0 ---诗
Poem.IdPoet可以为null。
我需要从诗人那里得到没有诗歌的所有记录,以及诗歌用语言= 1或语言= 2的诗人。语言1比2更具限制性。这意味着如果有一个诗人有2首诗(一个写在语言1上,另一个写在语言2上)必须只显示语言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)
)
这个选择显示没有诗歌的诗人,他们在语言1上有1首诗或在诗歌2上有1首诗。问题是当诗有2首诗时,一首是语言1而另一首是语言2,那么显示2条记录,我想只显示语言1上的诗歌记录,因为它比2更具限制性。
答案 0 :(得分:0)
不确定这是否有效,但想法是创建一个所有诗人的名单,如果他们写了一些东西,他们所有的诗。
Poets-table与诗歌联系在一起,包括所有诗人
select distinct poets.Name,
coalesce (l1.Text, l2.Text,'NONE') as Poem
from Poets
left join (
Poems l1
full join Poems l2
on l1.IdPoet = l2.IdPoet
)
on Poets.IdPoet = l1.IdPoet
where 1l.Language = 1 and l2.Language=2
(未测试的)
然而,如果一位诗人用一种语言写了不止一首诗,就会显示出来。我不知道这是不是你想要的。
答案 1 :(得分:0)
您可以使用Oracle的ROW_NUMBER()分析函数轻松完成此操作:
SELECT Name, Text FROM (
SELECT PT.Name, PM.Text, ROW_NUMBER() OVER (PARTITION BY PT.IdPoet ORDER BY PM.Language) RN
FROM POET PT
LEFT JOIN POEM PM ON (PT.IdPoet = PM.IdPoet)
WHERE PM.Language IS NULL OR PM.Language IN (1, 2)
) WHERE RN = 1
请注意,如果单个诗人的语言1中有多首诗歌,那么它只会选择从数据库中首先返回的诗歌。您可以在分区子句中向ORDER BY
添加另一个字段,以便根据您的需要首先按诗名等进行排序。
编辑:此外,如果您想要alzaimar提出的相同行为(即显示语言1中的所有诗歌),您可以使用DENSE_RANK()
函数代替{{1 }}
答案 2 :(得分:0)
如果您想使用最低语言值选择每首诗歌的信息 对于每一位诗人,以及没有诗歌的诗人,这个问题应该做:
SELECT * FROM Poet P
LEFT JOIN Poem ON Poem.IdPoet = P.IdPoet
where Poem.Language IS NULL
OR Poem.Language =
(SELECT MIN(Language) As L1
FROM Poem
WHERE Poem.IdPoet = P.IdPoet
GROUP BY Poem.IdPoet)
这里语言的最低值假定为1,并且查询也将使用高于2的语言值。