tags:

views:

161

answers:

6

I am lookign for the correct SQL code to join 2 tables and show only the last record of the details table.

I have a DB with 2 tables,

Deals 
   DealID
   Dealname
   DealDetails

DealComments
   dcID
   DealID
   CommentTime
   CommentPerson
   Comment

There are multiple comments for each Deal, but i would like to create a VIEW that displays all of the Deals and only the last Comment from each Deal (determined by the CommentTime) field

+4  A: 
select a.dealid
, a.dealname
, a.dealdetails
, b.dcid
, b.commenttime
, b.commentperson
, b.comment
from deals a, dealcomments b
where b.dealid = a.dealid
  and b.commenttime = (select max(x.commenttime)
                       from dealcomments x
                       where x.dealid = b.dealid)

EDIT: I didn't read the initial question close enough and didn't notice that all DEALS rows were needed in the view. Below is my revised answer:

select a.dealid
, a.dealname
, a.dealdetails
, b.dcid
, b.commenttime
, b.commentperson
, b.comment
from deals a left outer join (select x.dcid
, x.dealid
, x.commenttime
, x.commentperson
, x.comment
from dealcomments x
where x.commenttime = (select max(x1.commenttime)
                       from dealcomments x1
                       where x1.dealid = x.dealid)) b
on (a.dealid = b.dealid)
John Wagenleitner
Returns ths good results, but can have performance issue if the table dealcomments is big enough : you access the data twice !
Scorpi0
this works great however it only returns the deals that have comments. I would like to also see the deals that have no comments
Khalid Rahaman
@Khalid - I edited my answer, the new SQL should return all deals rows.
John Wagenleitner
excellent, just what i needed. Thanks John
Khalid Rahaman
A: 

Try this..

SELECT D.*,DC1.Comment 
FROM Deals AS D
   INNER JOIN DealComments AS DC1
        ON D.DealId = DC1.DealID
    INNER JOIN 
    (
        SELECT 
            DealID,
            MAX(CommentTime) AS CommentTime
        FROM DealComments AS DC2
        GROUP BY DealID
    ) AS DC2
        ON DC2.DealId = DC.DealId
            AND DC2.CommentTime = DC1.CommentTime
Atul
+1  A: 

Not very elegant, but works in Oracle :

select dealid,
       dealname,
       dealdetails,
       comment,
from
(
  select a.dealid,
         a.dealname,
         a.dealdetails,
         b.commenttime,
         b.comment,
         max(commenttime) over (partition by a.dealid) as maxCommentTime
  from deals a inner join dealcomments b on b.dealid = a.dealid
)
where comment = maxCommentTime
Scorpi0
Why do you characterize it as "not very elegant"?
mr_georg
A: 

Try this:

CREATE VIEW DealsWithLastComment
AS
   SELECT
       D.*, DC.*
   FROM
       Deals D INNER JOIN DealComments DC
       ON D.DealID = DC.DealID
       GROUP BY D.DealID, DC.CommentTime
       HAVING DC.CommentTime = MAX(DC.CommentTime)
PatrikAkerstrand
A: 
select
  d.DealID, dc1.dcID, dc1.Comment, dc1.CommentPerson, dc1.CommentTime
from
  Deals d
inner join
  DealComments dc1 on dc1.DealID = d.DealID
where
  dc1.CommentTime = (select max(dc2.CommentTime) from DealsComments dc2 where dc2.DealId = dc1.DealId)
bang
Same request as John Wagenleitner...
Scorpi0
Yes, same ANSWER as John, but I wrote it the same time and he posted it just seconds before me. Sorry for that ! But was it really worth a down vote ?!
bang
I don't know how SO works usually, i'm new, sorry ! :)
Scorpi0
Again, not completely correct: it is requested that "all of the Deals" are selected, but your inner join eliminates deals without comments
AlexKuznetsov
+1  A: 

Obligatory no-subquery-nowhere-answer:

select d.*
       , dc.*
from   Deals d
       left outer join DealComments dc 
       on d.DealID = dc.DealID
       left outer join DealComments dc1 
       on d.DealID = dc1.DealID 
   and 
       dc1.CommentTime > dc.CommentTime
where  dc1.CommentTime is null

Show me everything in Deals and DealComments when there exists no CommentTime greater than any given comment time for a particular DealID.

Edit: as Alex Kuznetsov astutely points out in a comment: the OP requested that all deals be displayed -- whether a deal has a comment or not. So I have changed the first JOIN from INNER to LEFT OUTER.

Adam Bernier
Time consuming, but beautiful !
Scorpi0
@Scorpi0: thanks! Time-consuming answers usually don't get much attention :)
Adam Bernier
Not completely correct: it is requested that "all of the Deals" are selected, but your inner join eliminates deals without comments
AlexKuznetsov
Thanks Alex, you're absolutely right. I have updated the answer.
Adam Bernier