web-dev-qa-db-fra.com

Comment sélectionner un seul enregistrement dans une jointure gauche

Je dois sélectionner un modèle spécifique dans la table Modèles à l'aide de sa clé ModelID. J'ai également besoin d'ajouter un texte de présentation de la table Model_Content. Toutefois, la table Models_Content comporte plusieurs renvois de contenu pour chaque modèle. Je dois sélectionner uniquement le premier texte de présentation.

Mes tables ressemblent à ceci:

 Models // table
 ModelID // pk
 Model // varchar

 Models_Content // table
 ContentID // pk
 ModelID // fk
 Content // varchar

 SELECT M.ModelID, M.Model, C.Content
 FROM   Models M LEFT JOIN Models_Content C ON M.ModelID =  C.ModelID
 WHERE      M.ModelID = 5

Comment ajuster ma requête pour sélectionner uniquement le tout premier texte de présentation d'un modèle spécifique?

22
Evik James
 SELECT
   M.ModelID, M.Model, C.Content
 FROM
   Models M
 LEFT JOIN
   Models_Content C
     ON C.ContentID = (SELECT MIN(ContentID) FROM Models_Content WHERE ModelID = M.ModelID)
 WHERE
   M.ModelID = 5

Ou

;WITH sorted_content AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY ModelID ORDER BY ContentID) AS itemID,
    *
  FROM
    Models_Content
)
 SELECT
   M.ModelID, M.Model, C.Content
 FROM
   Models M
 LEFT JOIN
   sorted_content C
     ON  C.ModelID = M.ModelID
     AND C.itemID  = 1
 WHERE
   M.ModelID = 5
40
MatBailie

La réponse de Sean est la meilleure solution spécifique mais il suffit d'ajouter une autre solution "généralisée"

SELECT M.ModelID,
       M.Model,
       C.Content
FROM   Models M
       OUTER APPLY (SELECT TOP 1 *
                    FROM   Models_Content C
                    WHERE  M.ModelID = C.ModelID
                    ORDER  BY C.ContentID ASC) C
WHERE  M.ModelID = 5  
9
Martin Smith
 SELECT TOP 1 M.ModelID, M.Model, C.Content
 FROM   Models M LEFT JOIN Models_Content C ON M.ModelID =  C.ModelID
 WHERE      M.ModelID = 5
 ORDER BY C.ContentID ASC
4
Sean

Cela peut être une extension de la réponse de Randy, mais ce n'est pas tout à fait clair pour moi.  

Pour des raisons de performances, je souhaitais réduire le nombre d'instructions SELECT dans ma requête. J'ai donc utilisé une instruction MIN dans la sélection principale au lieu de la dans la JOIN:

SELECT 
    table_1.id AS id, 
    table_1.name AS name,
    MIN(table_2.id) AS table_2_id 
FROM table_1
LEFT JOIN table_2 ON table_2.table_1_id = table_1.id
-- additional JOINs and WHERE excluded
GROUP BY table_1.id, table_1.name
LIMIT 5

Il peut y avoir des compromis en fonction de la quantité totale de données. IDK. Ma requête doit créer un tunnel dans les données à partir d'une condition dont plusieurs étapes ont été supprimées.

0
mbrakken

vous pouvez sélectionner le MIN ( contentID )

0
Randy