views:

82

answers:

2

Alright, so I'm putting together a path to select a revision of a particular novel:

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;

This returns all revisions that are in the Novel Master for each Novel Master that is in the catalog.

The problem is, I only want the FIRST revision of each novel master in the catalog. How do I go about doing that? Oh, and btw: my flavor of sql is hobbled, as many others are, in that it does not support the LIMIT Function.

*UPDATE*

So using answer 1 as a guide I upgraded my query to this:

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;

I get an error on the fourth line: "old"."revision": invalid identifier

SOLUTION Well, I had to go to another forum, but I got a working solution:

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

So this solution uses the JOIN mentioned by the OA, along with the IN keyword to match it to a revision.

+2  A: 

Something like this might work, it's called an exclusive left join:

....
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

The where clause filters out rows for which a newer revision exists. This effectively limits the query to the newest revisions.

In response to your comment, you could filter out only revisions that have a newer revision in the same NovelMaster. For example:

....
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. I don't think you can group JOINs and follow them with a group of ON conditions. An ON must directly follow its JOIN.

Andomar
I posted the second answer but I'll give you a vote up.
Kronass
Andomar: I already tested the sample I posted and it worked, so I would say you are wrong in assuming that you can not follow ONs after a group of JOINs.I also think you mean to add: NewerRevision.Revision > NovelRevision.Revision, but where does the NewerRevision table come from? I assume this is a clone of the original table, but how do I declare it in the query? Thx.
IcedDante
@IcedDante: NewerRevision is an alias for the NovelRevision table. I'll clarify by adding `as` in the query. I've never seen groups of JOINs work: What database are you using?
Andomar
SQL expert to the table: I posted an updated sample statement using the info in this answer, but I am still having problems. Please check out the update and reply.
IcedDante
@IcedDante: Try to add `and s.obid is null` to the where clause
Andomar
@Andomar: Sorry about that omission. So I added it and I now only get novels of the lowest revision '-'. for some novels, however, the lowest revision could be something like A1 or J, so a lot of records are being omitted.It's like I need a way to filter the revision for each novelMaster as opposed to the whole catalog, dig?
IcedDante
@IcedDante: You could left join back to the NovelMaster for the newer revision, and so limit the exclusion to newer revisions for the same NovelMaster. Example added to answer
Andomar
@Andomar: Can you have an AND clause in a Join from two different tables? I'm getting an invalid identifier error on the novelrevision table (line 3 of your fix)
IcedDante
@IcedDanty: Line 3 is not new in the fix, it's in the original solution as well? And yes you can reference any table you like after an `on` clause
Andomar
@Andomar: Sorry, but it's just not working. I revised the code in the UPDATE section. On line 4 I am getting an invalid identifier error. Any idea why?
IcedDante
@IcedDante: Not sure. Maybe it gets confused by HasNovelRevision being both a table alias and a normal table. Perhaps give all your table names an alias? As in `HasNovelRevision as CurrentRevision`
Andomar
@Andomar: put the final solution in the question. thanks for your help!
IcedDante
+1  A: 

You can use CTE Check this

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];

First it select the first revision written for each novel (assuming obid is novel foriegn key) by taking the smallest date and group them. then add it as join in your query

Kronass
What do the brackets indicate? Is it obvious what a SQL noob I am?
IcedDante
Kronass- apparently the Oracle sql I am using doesn't support the CTE tactic: "unsupported column aliasing". Thnx tho.
IcedDante