2009-06-28 15 views
5

io non sono del tutto sicuro se questo è l'approccio giusto, questa è la mia situazione:mysql - subquery e si unisce

Attualmente sto cercando di selezionare 15 gallerie e poi a sinistra unirsi con la tabella degli utenti attraverso il id ma voglio anche selezionare un'immagine casuale da ogni galleria, ma da quello che so non si può limitare il join sinistro (immagine) per ottenere solo un'immagine casuale senza fare una sottoquery.

Ecco quello che ho ottenuto finora, ma la sua non funziona come dovrebbe:

SELECT galleries.id, galleries.name, users.username, pictures.url 
FROM galleries 
LEFT JOIN users ON users.id = galleries.user_id 
LEFT JOIN pictures ON (
    SELECT pictures.url 
    FROM pictures 
    WHERE pictures.gallery_id = galleries.id 
    ORDER BY RAND() 
    LIMIT 1) 
WHERE active = 1 
ORDER BY RAND() 
LIMIT 15 

Ho anche cercato di fare questo con attivo Record ma mi sono bloccato dopo aver fatto due a sinistra si unisce, è possibile per fare ottenere un subquery qui:

$this->db->select('galleries.id, galleries.name, users.id as user_id, users.username'); 
$this->db->from('galleries'); 
$this->db->join('users', 'users.id = galleries.user_id','left'); 
$this->db->join('pictures','pictures.gallery_id = galleries.id AND','left'); 
$this->db->where('active',1); 

spero proprio di non disordinato, ma sto davvero iniziando a diventare confuso da tutte le query SQL ..

Edit: Active Record with CodeIgniter

+0

+1 per interessante la citazione di Active Record ... puoi modificare per includere un link? –

risposta

2

Si potrebbe prendere una foto a caso in una sottoquery:

select 
    g.name, u.username, 
    (select url from pictures p where p.gallery_id = g.gallery_id 
    order by rand() limit 1) as url 
from galleries g 
left join users u on g.user_id = u.id 
where g.active = 1 

Sulla base della sua commento, è possibile selezionare una foto per ogni galleria in un subquery. Questo presuppone che la tabella immagini abbia una colonna ID.

select 
    g.name, u.username, p.url, p.name 
from (
    select id, user_id, name, 
     (select id from pictures p 
     where p.gallery_id = g.gallery_id 
     order by rand() limit 1) as samplepictureid 
    from galleries 
    where g.active = 1 
) g 
left join users u on g.user_id = u.id 
left join pictures p on p.id = g.samplepictureid 
+0

È possibile recuperare due variabili dalle sottoquery? Tutto ciò che ottengo è "L'operando dovrebbe contenere 1 colonna (s)" Ad esempio se voglio l'url e il nome senza fare due sottocommissioni? – Dennis

+0

Una sottoquery come questa può recuperare solo una colonna (e una riga). Quale altra colonna si desidera recuperare? – Andomar

+0

Vorrei selezionare sia l'url che il nome dall'immagine, quindi devo fare due sottoquery per questo? – Dennis

1
SELECT 
    g.id, 
    g.name, 
    u.username, 
    p.url 
FROM 
    galleries g 
    INNER JOIN (SELECT DISTINCT 
     gallery_id, 
     (SELECT url FROM pictures ss WHERE ss.gallery_id = s.gallery_id 
      ORDER BY RAND() LIMIT 1) AS url 
    FROM 
     pictures s) p ON 
     g.id = p.gallery_id 
    LEFT OUTER JOIN users u ON 
     g.user_id = u.id 
WHERE 
    g.active = 1 

Questa interrogazione si spegne e selezionare una galleria, allora sarà trovare qualsiasi galleria con una foto (se si desidera tornare gallerie senza una foto, modificare INNER JOIN di LEFT OUTER JOIN, e starai bene). Dopo ciò, si unisce agli utenti. Ora, naturalmente, questo cucciolo sta per restituire ogni galleria fottuta per molti utenti che hai (hoorah!). Si consiglia di limitare l'utente nella clausola WHERE (ad esempio WHERE u.id = 123). Altrimenti, otterrai più risultati di quanto ti aspetteresti. Quello, o fai un INTERNO IN PARTITO su di esso.

+0

È meglio fare un join interno invece di fare come ha spiegato Andomar? – Dennis

+0

Il join consente di restituire più colonne e utilizzare quelle nell'istruzione select. Ho pensato che potesse essere così, ed è per questo che l'ho fatto in quel modo. – Eric