0

我想从与 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
Poet-1-------------N0---Poem的关系

Poem.IdPoet 可以为空。

我需要从 Poet 那里得到所有没有诗歌的记录,以及有语言 = 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 的诗歌或有 1 首语言 2 的诗歌。问题是当诗歌有 2 首诗歌,1 首语言 1 和其他语言 2 时,则显示 2 条记录,并且我只想在语言 1 上显示带有诗歌的记录,因为它比 2 更具限制性。

4

3 回答 3

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

(未经测试)

但是,如果诗人用一种语言写过不止一首诗,则两者都会显示。我不知道这是否是你想要的。

于 2013-01-27T10:12:13.667 回答
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按诗名等排序。

SQL小提琴


编辑:此外,如果您想要 alzaimar 提出的相同行为(即显示语言 1 中的所有诗歌),您可以使用该DENSE_RANK()功能而不是ROW_NUMBER().

于 2013-01-27T10:33:34.330 回答
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 的语言值。

于 2013-01-27T12:23:31.777 回答