SQL: Normativa per mostrare 1 bambino record per padre in una relazione uno-a-molti
-
23-08-2019 - |
Domanda
Ho 2 tabelle, una tabella di prodotto e di una tabella di immagine. I prodotti possono avere più di 1 immagine al record. Ho bisogno di un'istruzione SQL che elencherà 1 immagine al prodotto piuttosto che tutte le immagini al prodotto.
Un esempio ridotta del mio sforzo corrente è:
SELECT Product.RefCode, Img.ImgPath
FROM Product INNER JOIN (
SELECT ProductImg.ImgPath, ProductImg.PrdFK
FROM ProductImg
LIMIT 0,1) AS Img ON Product.PrdID = Img.PrdFK;
L'esempio precedente restituisce 0 risultati, tuttavia, se io rimuovere il limite 0,1 dal Sub SELEZIONARE ottengo una lista completa di tutti i prodotti e tutte le immagini.
Voglio solo 1 record di immagine per ogni record del prodotto da restituire.
Ho rivisto "un programmatore" Codice a MySQL e funziona benissimo.
SELECT Product.RefCode,
(Select ProductImg.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK LIMIT 0,1) AS ImgPath
FROM Products
Per qualche ragione quando si cerca la soluzione "di Bill Karwin", ha inviato al server di carico per lungo tempo.
Soluzione
Questo dovrebbe funzionare:
SELECT Product.RefCode,
(Select Img.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK LIMIT 0,1) As ImgPath
FROM Product
Se si dispone di un modo per determinare quale immagine deve il ritorno di selezione, quindi è possibile aggiungere un dove e forse un ordinazione in sub-select.
Nel seguente esempio, avremo solo l'ultima delle immagini attiva.
SELECT Product.RefCode,
(Select Img.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK
And IsActive = 1
Order By EntryDate Desc LIMIT 0,1) As ImgPath
FROM Product
A cura e corretta 'Top 1' a 'limitare 0,1'.
Altri suggerimenti
MySQL ha una certa flessibilità qui. È possibile utilizzare GROUP BY per limitare il risultato di una riga per prodotto, quindi MySQL sarà scegliere quale immagine arbitrariamente. In pratica, si tende ad essere l'immagine che viene memorizzato fisicamente prima nel database, ma non hanno alcun controllo su questo.
SELECT p.RefCode, i.ImgPath
FROM Product p INNER JOIN ProductImg i
ON (p.PrdID = i.PrdFK)
GROUP BY p.PrdID;
Se si desidera 1 specifica immagine per prodotto, ci sono modi per fare anche questo. È necessario includere che nei vostri requisiti. : -)
Se si dispone di una colonna ID sul tavolo Immagine, questa dovrebbe funzionare (non importa quale sia il prodotto SQL o versione) -
SELECT p.RefCode, i1.ImgPath FROM Product p INNER JOIN ProductImg i1 ON p.PrdId = i1.PrdFk LEFT JOIN ProductImg i2 ON i1.PrdId = i2.PrdId AND i1.ImgId < i2.ImgId WHERE i2.ImgId IS NULL
Quello che vi serve è una bandiera sul tavolo Immagine di specificare se è l'immagine principale da visualizzare. Ci sono modi di tirare un'immagine arbitraria, ma penso che sarebbe meglio per assicurarsi che si tira l'immagine corretta.