web-dev-qa-db-fra.com

SQL Joindre trois tables

J'apprends peu à peu les requêtes SQL avancées et je suis assez embarrassé par un problème:

J'ai trois tables: news, author et images. Chaque champ de la table news (newsID) est un article d'actualité auquel est associé un auteur dans la table author (authorID) et peut associer un nombre illimité d'images dans la table images. Chaque image a et associé (newsID). Ainsi, chaque histoire a un auteur mais peut avoir plusieurs images.

Je veux faire une liste de tous les reportages et utiliser un seul des images sous forme de vignette. Le problème est que toute requête SQL que j'essaie de répertorier les éléments news avec me donne des résultats égaux au nombre d'images de la table images au lieu du nombre d'éléments news.

Je ne sais pas où aller d'ici. Toute aide serait grandement appréciée.

14
Robert Robinette

Si les 3 tables en question sont [news], [author] et [image] avec les colonnes appropriées, alors 

Approche par table dérivée

vous pouvez avoir une table d'images dérivée pour obtenir une image par news, puis la joindre aux tables news et author comme indiqué .. Ceci a été écrit et testé dans 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

Vous pouvez remplacer les jointures externes gauches par des jointures internes si vous n'avez pas besoin de nouvelles sans images.

Approche de sous-requête corrélée (comme suggéré par Marcelo Cantos)

Si imageData est stocké sous forme de texte ou d'image, le MAX dans la table dérivée ne fonctionnerait pas. Dans ce cas, vous pouvez utiliser une sous-requête corrélée comme ceci:

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

22
Kash

Une option consiste à ajouter le prédicat suivant:

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

Notez que cela exclut les articles sans image. Si vous ne le souhaitez pas, vous aurez besoin d'une jointure à gauche sur les images et d'une condition supplémentaire sur la commande WHERE:

FROM news LEFT JOIN images ...
...
WHERE imageID IS NULL
   OR imageID = (SELECT MAX(imageID)
                   FROM image
                  WHERE newsID = news.newsID)
2
Marcelo Cantos

Vous pouvez modifier l'ordre en sélectionnant la sous-sélection pour obtenir 1 image par ligne d'actualités que vous recherchez ...

select
....
from news n
left outer join images i on i.imageID = (
    select top 1 i2.imageID 
    from images i2 
    where i2.newsID = n.newsID
    order by --??
)
0
dotjoe

Si vous avez 3 tables dans mysql et que vous voulez les joindre ensemble. Par exemple, j'ai 3 tables 1 étudiant 2 sujets 3 scores Maintenant, je veux rejoindre les étudiants avec sujet et scores. donc nous vous cette syntaxe: select * from sujet de jointure interne sujet étudiant jointure interne;

0
user2147772