-
Notifications
You must be signed in to change notification settings - Fork 11.4k
[10.x] Add Lateral Join to Query Builder #50050
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
Conversation
I think we would normally want to keep that translation to "lateral" SQL syntax in the query "grammar" layer. |
@taylorotwell Yes, that is probably best. |
SQL server has Cross Apply And Outer Apply. CROSS APPLY = lateral join Don't think it supports right lateral join https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/ |
@crissi Postgres and MySQL does not support right lateral join neither (it would make no sense). My mistake. Removing it from the PR now. I will look into translating it into cross/outer apply for SQL server as well. |
030f769
to
8e589c5
Compare
I have moved "lateral" and "on true" translation into the grammar layer now, and added support for SQL server. I have tested @taylorotwell I am a bit uncertain of two things in the PR:
|
Just wanna chime in because MariaDB hasn't added support for lateral join yet. And Laravel considers MySQL and MariaDB as same RDBMS under |
I know. MariaDB uses the same translations as MySQL, so it will fail with a syntax error as it is not supported yet. I do believe they are planning on implementing support though. |
1f9a007
to
0d0539f
Compare
👍 for this feature. @tpetry and I were just talking about it last week. We can also use lateral joins to improve the performance of some of Laravel's own queries. Tobias has already implemented lateral joins for PostgreSQL in his laravel-postgresql-enhanced package and I would take inspiration from his code:
I also think it would be good to have integration tests (under |
@staudenmeir Good tip! I will checkout this package in detail and draw some inspiration from there.
|
@staudenmeir I am looking into custom join constraints ( I tested lateral joins with custom constraints outside the subquery in Postgres. The results are the same as when I put the constraints inside the subquery. Performance also seems to be about the same. Are there any use cases where putting the constraints outside the subquery provides an advantage? If not, I am afraid of just adding in unnecessary complexity that can cause confusion. |
There's not really any benefit of using a join condition compared to just always using Would be great if you could build the API to be the same as mine (when using the same name) to not break my package. You could e.g. only use the first two params (and always do |
@tpetry I am leaning against dropping the join conditions then, to keep it simple and consistent across different SQL implementations. We have three choices to not break your current implementation in
|
I would suggest these three methods:
They fit to my implementation as I only add some parameters - which I believe are not even usefull. The So it would make the concept more easy by saying that the join target is always a subquery that needs to apply the filters and all results are used - as expected. |
@tpetry @staudenmeir I suggest reverting to If I drop the A lateral join in its simplest form is I would also like to avoid using "cross" in the method names, unless we explicitly include a cross join method. A lateral join is always used in a cross join behaviour, but you would probably write the SQL as In short: I think dropping "Sub" from the method names is a fair trade-off for not breaking the package, and not including any unused parameters. |
Renaming to not break my package would be nice 👍 But I still don't get the |
The same is done for |
Yes 😅 |
@staudenmeir I rewrote the code to use a |
Thanks. Can you please add integration tests? The queries should be tested against actual databases. |
Should I create separate |
Yes, please. |
abf8b2f
to
08b7b32
Compare
@staudenmeir I added some simple integration tests now. They are skipped for MySQL < 8.0.14 and MariaDB. |
Excellent, thanks. From my side, the PR is ready (I can't approve it). |
@staudenmeir Great, thanks! |
6f2ce74
to
5d54847
Compare
@staudenmeir I made a small change to the integration tests. |
Thanks! |
@Bakke can you send a PR to laravel/docs for this? |
@taylorotwell Yes, of course! I will create the PR as soon as possible. |
This PR adds lateral join methods to the query builder. I have based the methods and tests upon
joinSub
as the behaviour is somewhat similar.Lateral joins have been supported in PostgreSQL for a long time (since 9.3), and are also supported in MySQL since 8.0.14.
The lateral joins are a bit similar to a subquery join, as the right-hand table is expressed as a subquery. However the right-hand expression is executed for every row, which opens up for new use cases. It is particularly useful for joining in the top 'N' rows related to the main query. In example: