Forcefield Forcefield - 5 months ago 8
MySQL Question

Joining different WHERE clauses on mySQL multiple select statement

As someone who constantly has problems with databases, I'm trying to look for a solution that optimizes my database calls. Scenario is this, I'm trying to get all rows of items directly owned by the user, but also I want to get the rows of items where the user roles acts as a guest. My current query works, but I think it isn't the best forged solution for what I'm trying to achieve. This get me the results I want, but I fear when there are hundreds of rows this will get terribly slow

set @UsrId = 23;
(SELECT Eventos.Fecha, Eventos.InformacionDelEvento, Eventos.PosicionGpsSiNo, Eventos.InformacionGps, Dispositivos.Nombre, CatalogoDeEventos.Descripcion
FROM Eventos, CatalogoDeEventos, Dispositivos, DispositivosxUsuario
WHERE Eventos.IdEvento = CatalogoDeEventos.Id
AND Dispositivos.IdentificadorUnico = Eventos.IdDispositivo
AND DispositivosxUsuario.IdDispositivo = Dispositivos.Id
AND Dispositivos.Invisible = 0
AND DispositivosxUsuario.IdUsuario = @UsrId
ORDER BY Fecha DESC)
UNION
(SELECT Eventos.Fecha, Eventos.InformacionDelEvento, Eventos.PosicionGpsSiNo, Eventos.InformacionGps, Dispositivos.Nombre, CatalogoDeEventos.Descripcion
FROM Eventos, CatalogoDeEventos, Dispositivos, DispositivosxUsuario, Seguidores
WHERE Eventos.IdEvento = CatalogoDeEventos.Id
AND Dispositivos.IdentificadorUnico = Eventos.IdDispositivo
AND DispositivosxUsuario.IdDispositivo = Dispositivos.Id
AND Dispositivos.Invisible = 0
AND Seguidores.IdUsuario = DispositivosxUsuario.IdUsuario
AND Seguidores.IdSeguidor = @UsrId
ORDER BY Fecha DESC)


So both queries have this same block

SELECT Eventos.Fecha, Eventos.InformacionDelEvento, Eventos.PosicionGpsSiNo, Eventos.InformacionGps, Dispositivos.Nombre, CatalogoDeEventos.Descripcion
FROM Eventos, CatalogoDeEventos, Dispositivos, DispositivosxUsuario
WHERE Eventos.IdEvento = CatalogoDeEventos.Id
AND Dispositivos.IdentificadorUnico = Eventos.IdDispositivo
AND DispositivosxUsuario.IdDispositivo = Dispositivos.Id
AND Dispositivos.Invisible = 0


They differ on the lines above this, so far I haven't figured a way of getting both results on a single call

Answer

this should work

SELECT Eventos.Fecha, Eventos.InformacionDelEvento, Eventos.PosicionGpsSiNo,     Eventos.InformacionGps, Dispositivos.Nombre, CatalogoDeEventos.Descripcion
FROM Eventos, CatalogoDeEventos, Dispositivos, DispositivosxUsuario, Seguidores
WHERE Eventos.IdEvento = CatalogoDeEventos.Id 
    AND Dispositivos.IdentificadorUnico = Eventos.IdDispositivo
    AND DispositivosxUsuario.IdDispositivo = Dispositivos.Id
    AND Dispositivos.Invisible = 0
    AND Seguidores.IdUsuario = DispositivosxUsuario.IdUsuario
    AND (
      (Seguidores.IdUsuario = DispositivosxUsuario.IdUsuario 
        AND Seguidores.IdSeguidor = @UsrId) 
      OR DispositivosxUsuario.IdUsuario = @UsrId)
ORDER BY Fecha DESC

as was mentioned in the comments, this effectively left joins on Sequidores and that would probably have been more obvious if the query was written with the newer join syntax.

Re-written to use newer join syntax

SELECT e.Fecha, e.InformacionDelEvento, e.PosicionGpsSiNo, e.InformacionGps, d.Nombre, cde.Descripcion
FROM Eventos e 
    INNER JOIN CatalogoDeEventos cde ON e.IdEvento = cde.Id
    INNER JOIN Dispositivos d ON d.IdentificadorUnico  = e.IdDispositivo
    INNER JOIN DispositivosxUsuario du ON du.IdDispositivo = d.Id
    LEFT JOIN Seguidores s ON s.IdUsuario = du.IdUsuario 
WHERE d.Invisible = 0 
  AND (Seguidores.IdSeguidor = @UsrId 
        OR DispositivosxUsuario.IdUsuario = @UsrId)
ORDER BY Fecha DESC