Complemento a Eager loading Associations y entender las diferencias entre Join, Left Join y Right Join


_DSC1483Hace poco escribía un post impulsado por avanzar en RubyOnRails y titulaba el post: ¿Cómo puedo reducir el número de Queries utilizando RubyOnRails con Active Records? joins, include – Eager loading Associations y en una tertulia de mañana con algunos compañeros de trabajo sobre el tema include y join si hay o no diferencias, pensé que dicho post no quedara lo suficientemente claro y por no dejar temas difusos escribo el título de “Complemento a Eager loading Associations y entender las diferencias entre Join, Left Join y Right Join“. La cuestión es que un include y un join hablando en Rails no es lo mismo y no sólo esa es la cuestión, es que nada tienen que ver uno con el otro.

Me explico

Cuando hablaba sobre el uso del include y del join para mejora de rendimiento con la técnica Eager loading, decía que las tablas que necesitábamos son, productos en nuestro modelo Product y que teníamos asociadas unas categorías en una tabla de categorías en nuestro modelo de Category  y que también puede darse el caso que necesitemos crear comentarios a nuestros productos y que en ese caso tendremos nuestra tabla de comentarios en nuestro modelo de Review. También tendremos nuestros usuarios en el modelo User.

Si pasamos a consola de Rails y escribimos Product.includes(:category, :reviews) esto nos arroja un resultado de 3 querires:

Product Load (0.5ms) SELECT “products”.* FROM “products”
Category Load (0.3ms) SELECT “categories”.* FROM “categories” WHERE “categories”.”id” IN (2, 3, 4, 5, 7, 8, 9, 10, 6)
Review Load (0.4ms) SELECT “reviews”.* FROM “reviews” WHERE “reviews”.”product_id” IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37)

Ahora bien si lo que hacemos en un Product.joins(:category, :reviews) nos arroja como resultado en esta otra ocasión de:

Product Load (0.4ms) SELECT “products”.* FROM “products” INNER JOIN “categories” ON “categories”.”id” = “products”.”category_id” INNER JOIN “reviews” ON “reviews”.”product_id” = “products”.”id”

Ahora bien, este último resultado si no hay relaciones de registros entre ellas no nos devuelve nada, para eso necesitamos hacer otro tipo de  join como Product.joins(“left outer join categories on category_id = categories.id”).

Pues bien, dados estos pasos aclaratorios del post ¿Cómo puedo reducir el número de Queries utilizando RubyOnRails con Active Records? joins, include – Eager loading Associations creo que si dejo el post tal cual lo escribí,  tengo la sensación que no queda completo y por eso quiero complementarlo con las diferencias entre Join, Left Join y Right Join.

Veamos las posibles combinaciones entre las tablas donde cada registro de la tabla Products se combina con otro de la tabla Categories pero además que cumpla una serie de condiciones. Por ejemplo, necesitamos saber los Productos de una Categoría, para lo que haremos es la query siguente:

select * from products a, categories b where a.category_id = b.id

Para esa misma query, tenemos la posibilidad de expresar con un Join Inner:

select * from products a inner join categories b on a.category_id = b.id

Ahora bien, si necesitamos un listado de Productos que tengan o no asignada una Categoría, lo que tendríamos que hacer sería un:

select * from products a left join categories b on a.category_id = b.id

Lo que se traduce que en cualquiera de los casos que necesitamos un join por la izquierda, esto quiere decir que, necesitamos saber todos los registros de la tabla izquierda tengan o no correspondencia con la tabla derecha, pero si necesitamos un right join hace lo mismo pero para todos los registros de la tabla derecha tengan o no correspondencia con la de la izquierda.

Seguramente vuelva a la carga con algún detalle más, según tenga más inquietudes al respecto…….

Un comentario en “Complemento a Eager loading Associations y entender las diferencias entre Join, Left Join y Right Join

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s