it-swarm.it

Come selezionare un singolo record in un join di sinistra

Devo selezionare un modello specifico dalla tabella Models usando la sua chiave ModelID. Devo anche aggiungere un miscuglio di contenuti dalla tabella Model_Content. La tabella Models_Content, tuttavia, presenta diversi tipi di contenuti per ciascun modello. Devo selezionare solo il primo blurb.

I miei tavoli hanno questo aspetto:

 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

Come aggiusto la mia query per selezionare solo il primo blurb di contenuti per un modello specifico?

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

O

;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 risposta di Sean è la migliore soluzione specifica, ma solo per aggiungere un'altra soluzione "generalizzata"

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

Cambia il tuo JOIN in:

LEFT JOIN (SELECT ModelID, MAX(Content) as Content FROM Models_Content GROUP BY ModelID)

Questo presuppone che non ti interessa quale Content ottieni.

1
JNK

Potrebbe essere un'espansione sulla risposta di Randy, ma non mi è del tutto chiaro.  

Per motivi di prestazioni, volevo ridurre al minimo il numero di istruzioni SELECT nella mia query, quindi ho usato un'istruzione MIN all'interno della selezione primaria anziché all'interno di 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

Potrebbero esserci dei compromessi in base alla quantità totale di dati. IDK. La mia query deve scavare nei dati da una condizione rimossa da diversi passaggi.

0
mbrakken

puoi selezionare MIN ( contentID )

0
Randy