2009-06-28 10 views
5

no estoy muy seguro de si este es el enfoque correcto, esto es mi situación:MySQL - subconsultas y se une a

Actualmente estoy tratando de seleccionar 15 galerías y luego a la izquierda unirse con la tabla de usuario a través de la id pero también quiero seleccionar una imagen al azar de cada galería, sin embargo, por lo que sé, no se puede limitar la combinación izquierda (imagen) para que solo se recoja una imagen al azar sin hacer una subconsulta.

Esto es lo que tengo hasta ahora, pero no su trabajo como debería:

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 

También trataron de hacer esto con Active Record pero me quedé atrapado después de hacer dos a la izquierda se une, es posible hacer llegar una sub consulta aquí:

$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); 

espero su no desordenado, pero estoy empezando a ser confuso por todas las consultas SQL ..

Editar: Active Record with CodeIgniter

+0

+1 por cita interesante de Active Record ... ¿podría editar para incluir un enlace? –

Respuesta

2

Usted se pudo obtener una foto al azar en una subconsulta:

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 

Basado en su comentario, puede seleccionar una imagen para cada galería en una subconsulta. Esto supone que la tabla de imágenes tiene una columna de 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

¿Es posible recuperar dos variables de las subconsultas? Todo lo que obtengo es "Operando debe contener 1 columna (s)" Por ejemplo, si quiero la url y el nombre sin hacer dos sub-consultas? – Dennis

+0

Una subconsulta como esta solo puede recuperar una columna (y una fila). ¿Qué otra columna le gustaría recuperar? – Andomar

+0

Me gustaría seleccionar tanto la url como el nombre de la imagen, entonces tengo que hacer dos sub-consultas para esto? – 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 

Esta consulta se apagará y seleccione una galería, entonces se encontrará ninguna galería con una imagen (si desea volver galerías sin una imagen, cambiar INNER JOIN de combinación externa izquierda, y estarás bien). Después de eso, se une a los usuarios. Ahora, por supuesto, este cachorro va a devolver cada galería de frigging para la cantidad de usuarios que tenga (¡hoorah!). Es posible que desee limitar al usuario en la cláusula WHERE (por ejemplo, WHERE u.id = 123). De lo contrario, obtendrás más resultados de los que esperarías. Eso, o haz un INNER JOIN en él.

+0

¿Es mejor hacer una unión interna en lugar de hacerlo como explicó Andomar? – Dennis

+0

La unión le permite devolver varias columnas y usarlas en su declaración de selección. Pensé que este podría ser el caso, y es por eso que lo hice así. – Eric