从许多sql连接中选择第一行

时间:2010-04-01 21:32:48

标签: sql select join inner-join

好吧,所以我正在整理一条选择特定小说修订版的路径:

SELECT Catalog.WbsId, Catalog.Revision, NovelRevision.Revision
  FROM Catalog, BookInCatalog
    INNER JOIN NovelMaster
      INNER JOIN HasNovelRevision
        INNER JOIN NovelRevision
        ON HasNovelRevision.right = NovelRevision.obid
      ON HasNovelRevision.Left=NovelMaster.obid
    ON NovelMaster.obid = BookInCatalog.Right
  WHERE  Catalog.obid = BookInCatalog.Left;

这将返回目录中每个小说大师的小说大师中的所有修订。

问题是,我只想在目录中对每个小说大师进行第一次修订。我该怎么做呢?哦,顺便说一下:我的sql的味道很多,因为它不支持LIMIT功能。

**** **** UPDATE

因此,使用答案1作为指南我将查询升级为:

SELECT Catalog.wbsid
FROM Catalog, BookInCatalog, NovelVersion old, NovelMaster, HasNovelRevision
LEFT JOIN       NovelVersion newRevs
ON           old.revision < newRevs.revision AND HasNovelRevision.right = newRevs.obid
LEFT JOIN       HasNovelRevision NewerHasNovelRevision
ON           NewerHasNovelRevision.right = newRevs.obid
LEFT JOIN       NovelMaster NewTecMst
ON           NewerHasNovelRevision.left = NewTecMst.obid
WHERE Catalog.programName = 'E18' AND Catalog.obid = BookInCatalog.Left
AND BookInCatalog.right = NewTecMst.obid AND newRevs.obid = null
ORDER BY newRevs.documentname;

我在第四行收到错误: “旧”。“修订版”:标识符无效

好吧,我不得不去另一个论坛,但我找到了一个有效的解决方案:

select nr1.title, nr1.revision
from  novelrevision nr1
where nr1.revision in (select min(revision) from novelrevision nr2
    where  nr1.title = nr2.title)

因此,此解决方案使用OA提到的JOIN以及IN关键字将其与修订版本匹配。

2 个答案:

答案 0 :(得分:2)

这样的东西可能会起作用,它被称为独占左连接:

....
INNER JOIN  NovelRevision
ON          HasNovelRevision.right = NovelRevision.obid
LEFT JOIN   NovelRevision as NewerRevision
ON          HasNovelRevision.right = NewerRevision.obid
            AND NewerRevision.revision > NovelRevision.revision
...
WHERE       NeverRevision.obid is null

where子句筛选出存在较新修订版的行。这有效地将查询限制为最新版本。

在回复您的评论时,您只能过滤掉同一NovelMaster中具有较新版本的修订版。例如:

....
LEFT JOIN   NovelRevision as NewerRevision
ON          HasNovelRevision.right = NewerRevision.obid
            AND NewerRevision.revision > NovelRevision.revision
LEFT JOIN   HasNovelRevision as NewerHasNovelRevision
ON          NewerHasNovelRevision.right = NewerRevision.obid
LEFT JOIN   NovelMaster as NewerNovelMaster
ON          NewerHasNovelRevision.left = NewerNovelMaster.obid
            AND NewerNovelMaster.obid = NovelMaster.obid
....
WHERE       NeverNovelMaster.obid is null

P.S。我不认为你可以将JOIN分组并按照一组ON条件跟随它们。 ON必须直接跟随其加入。

答案 1 :(得分:1)

您可以使用CTE 检查一下

WITH NovelRevesion_CTE(obid,RevisionDate)
AS
(
SELECT obid,MIN(RevisionDate) RevisionDate FROM NovelRevision Group by obid
)
SELECT Catalog.WbsId, Catalog.Revision, NovelRevision.Revision 
  FROM Catalog, BookInCatalog 
    INNER JOIN NovelMaster 
      INNER JOIN HasNovelRevision 
        INNER JOIN NovelRevesion
            INNER JOIN NovelRevesion_CTE
        ON HasNovelRevision.[right] = NovelRevision.obid 
      ON HasNovelRevision.[Left]=NovelMaster.obid 
    ON NovelMaster.obid = BookInCatalog.[Right]
    ON NovelRevesion_CTE.obid = NovelRevesion.obid
  WHERE  Catalog.obid = BookInCatalog.[Left];

首先,它选择为每本小说编写的第一个修订版(假设obid是新颖的foriegn键),取最小的日期并将它们分组。 然后在查询中将其添加为联接