-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL JOIN with nested subquery/ies #9
Comments
Hey @atrost, This is another tough one. It looks like activerecord itself doesn't support this very well. Like all things activerecord/arel however, it's just a matter of coming up with the right incantation :) First of all - as you discovered - this works: Post.select(Post.where(id: 1)) It generates a subquery inside the Post.joins(Comment.where(id: 1)) We can however construct the join and table alias manually: t = Arel::Table.new('t')
Post
.joins(
Post.arel_table.join(
Arel::Nodes::TableAlias.new(Comment.where(id: 1).arel, 't'),
Arel::Nodes::InnerJoin
).on(
t[:post_id].eq(Post.arel_table[:id])
).join_sources
) Fortunately this works and produces the following SQL query: SELECT "posts".* FROM "posts"
INNER JOIN (SELECT "comments".* FROM "comments" WHERE "comments"."id" = 1) "t"
ON "t"."post_id" = "posts"."id" Un fortunately it only seems to work for activerecord 5.2. For versions < 5.2, activerecord appears to leave bind variables for nested subqueries behind (for joins at least), and ends up emitting question marks instead of constants. Eg: SELECT "posts".* FROM "posts"
INNER JOIN (SELECT "comments".* FROM "comments" WHERE "comments"."id" = ?) "t"
ON "t"."post_id" = "posts"."id" We can add the bind variables back in by hand, but at this point it really feels like we're fighting against the library. Instead, let's simply convert the subquery into raw SQL and wrap it with parens: Post
.joins(
Post.arel_table.join(
Arel::Nodes::TableAlias.new(Arel.sql("(#{Comment.where(id: 1).to_sql})"), 't'),
Arel::Nodes::InnerJoin
).on(
t[:post_id].eq(Post.arel_table[:id])
).join_sources
) It works! I'll see if I can add this functionality to Scuttle. |
Hey @camertron |
It seems Scuttle cannot handle queries with a subquery inside a JOIN. The following example uses only one level of nesting:
Scuttle turns this to:
The nested
SELECT
inside the LEFT OUTER JOIN statement gets ignored..Scuttle does recognize subquery patterns like this:
The text was updated successfully, but these errors were encountered: