Tengo varias tablas de las que estoy tratando de obtener algunos datos, y estoy muy cerca, pero no puedo cerrar el trato.Necesito un gurú de SQL para una consulta compleja
tengo las siguientes tablas:
- EVENTO
- USUARIO
- AMIGO
- USER__FRIEND
- EVENT__INVITATION
USUARIO y AMIGO están vinculados a través de la mesa USER__FRIEND (que contiene un USER_ID y un campo FRIEND_ID)
EVENT__INVITATION vincula un evento con una amiga (que tiene EVENT_ID y INVITEE_ID)
que estoy tratando de conseguir todos los eventos en los que:
- soy el creador del evento ($ MyUserID = EVENT.CREATOR_ID)
- o me invitan al evento ($ MyUserID = EVENT__INVITATION.INVITEE_ID)
- o uno de mis amigos es el creador del evento ($ MyUserID = USER__FRIEND.USER_ID Y eN EVENT.CREATOR_ID (lista de mis amigos))
- o uno de mis amigos es invitado al evento ($ MyUserID = USER__FRIEND.USER_ID Y EN EVENT__INVITATION.INVITEE_ID (lista de mis amigos))
Hay algunas otras condiciones WHERE alrededor de otros parámetros, pero creo Puedo resolverlos por mi cuenta.
En este momento, la única forma en que podía hacer que esto funcionara era con UNION, que creo que debía ser una salida de emergencia, y si tenía mejores habilidades, podía usarla.
Entonces, la pregunta es, ¿se puede hacer esto con una consulta única y económica que no utiliza UNIÓN?
Esto es lo que tengo hasta ahora, que lleva a cabo todo excepto los eventos que mis amigos están invitados a (23 es la aprobada en ID de usuario, en este caso):
SELECT e.*
FROM event e
LEFT JOIN event__invitation ei ON ei.event_id = e.id
LEFT JOIN user__friend uf ON uf.friend_id = ei.invitee_id
LEFT JOIN friend f ON f.id = uf.friend_id
WHERE (ei.invitee_id = 23 OR e.creator_id = 23 OR uf.user_id = 23 OR f.user_id = e.creator_id)
AND e.start_time >= 1348000000
y esta es la consulta con el UNION:
SELECT e.* FROM event e
INNER JOIN event__invitation ei ON ei.event_id = e.id
INNER JOIN user__friend uf ON uf.friend_id = ei.invitee_id
WHERE (e.creator_id = 23 OR ei.invitee_id = 23 OR uf.user_id = 23)
UNION
SELECT e1.* FROM event e1
WHERE e1.creator_id IN (
SELECT f1.user_id FROM friend f1
INNER JOIN user__friend uf1 ON uf1.friend_id = f1.id
WHERE uf1.user_id = 23
AND f1.user_id IS NOT NULL
);
Hay más en la consulta que hace que el uso de UNION no sea deseable. Tengo un cálculo trigonométrico complejo que estoy haciendo en la selección principal, y estoy ordenando los resultados por ese valor. Creo que puede estropear el conjunto de resultados.
¡Gracias por cualquier ayuda!
¿Estás seguro de que no te faltan las que el amigo es el creador? – CrazyCasta
Sé que se siente más viril hacerlo todo en una gran unión, pero sospecho que la UNIÓN es más eficiente. – Barmar
@Loco: No, ese está ahí (mira la última O de la cláusula WHERE). – Raconteur