Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Join three tables

Tags:

sql

database

join

I'm learning advanced SQL queries little by little and I'm fairly stumped with a problem:

I have three tables: news, author, and images. Each field in the news table (newsID) is a news story, which then has an associated author in the author table (authorID) and can have any number of images associated in the images table. Each image has and associated (newsID). So each story has one author but can have several images.

I want to make a list of all news stories and use just one of the images as a thumbnail image. The problem is that any sql query I try to list the news items with gives me results equal to the number of images in the images table rather than the number of news items.

I don't know where to go from here. Any help would be greatly appreciated.

like image 525
Robert Robinette Avatar asked Nov 04 '11 23:11

Robert Robinette


People also ask

Can we join 3 tables in SQL?

It is possible to use multiple join statements together to join more than one table at the same time. To do that you add a second INNER JOIN statement and a second ON statement to indicate the third table and the second relationship.

How join 3 tables inner join SQL?

The syntax for multiple joins: SELECT column_name1,column_name2,.. FROM table_name1 INNER JOIN table_name2 ON condition_1 INNER JOIN table_name3 ON condition_2 INNER JOIN table_name4 ON condition_3 . . . Note: While selecting only particular columns use table_name.

Can you join multiple tables in SQL?

An SQL query can JOIN multiple tables. For each new table an extra JOIN condition is added. Multi-Table JOINs work with SELECT, UPDATE, and DELETE queries.


2 Answers

If the 3 tables in question are [news], [author] and [image] with appropriate columns, then

Derived Table approach

you can have a derived image table to get one image per news and then join it with the news and author table as shown. This has been written and tested in SQL Server.

SELECT  
      N.[newsStoryTitle]
        ,A.authorName
        ,I.imageData1
  FROM [news] N
  LEFT OUTER JOIN author A ON A.newsID = N.newsID
  LEFT OUTER JOIN 
    (
    SELECT newsID, MAX(imageData) AS imageData1 FROM [image] 
    GROUP BY newsID
    )  AS I ON I.newsID = N.newsID
ORDER BY N.newsID

You could replace the LEFT OUTER JOINs with INNER JOINs if you do not need news without any images.

Correlated Subquery approach (as suggested by Marcelo Cantos)

If the imageData is stored as a text or image, then the MAX in the derived table wouldn't work. In that case, you can use a correlated subquery like this:

SELECT  N.newsStoryTitle ,
        A.authorName ,
        I.imageData
FROM    dbo.news N
        INNER JOIN dbo.author A ON N.newsID = A.newsID
        INNER JOIN dbo.image I ON N.newsID = I.newsID
WHERE   imageID = ( SELECT  MAX(imageID)
                    FROM    dbo.image
                    WHERE   newsID = N.newsID
                  )
ORDER BY n.newsID

Database Diagram

like image 116
Kash Avatar answered Sep 29 '22 15:09

Kash


One option is to add the following predicate:

FROM news JOIN images ...
...
WHERE imageID = (SELECT MAX(imageID)
                   FROM image
                  WHERE newsID = news.newsID)

Note that this excludes news items without an image. If you don't want this, you'll need a left join on images and an additional condition on the WHERE:

FROM news LEFT JOIN images ...
...
WHERE imageID IS NULL
   OR imageID = (SELECT MAX(imageID)
                   FROM image
                  WHERE newsID = news.newsID)
like image 23
Marcelo Cantos Avatar answered Sep 29 '22 15:09

Marcelo Cantos