Where Clause on join functions
JimBeem opened this issue · comments
Issue type:
[ ] Question
[ ] Bug report
[x ] Feature request
[ ] Documentation issue
Database system/driver:
[ ] Postgres
[x ] MSSQL
[ ] MySQL
[ ] MariaDB
[ ] SQLite3
[ ] Oracle
[ ] Amazon Redshift
typed-knex version:
[ x] latest
[ ] @next
[ ] 0.x.x
(or put your version here)
Knex.js version:
Steps to reproduce or a small repository showing the problem:
Given a one to many relationship where I want all rows of table 1 regardless of presence of a table 2 row with a specific value
What I have to do to get what I want:
typedKnex.query(Table1)
.leftOuterJoinJoinTableOnFunction('t2', Table2, (join) => {
(t1) => t1.c1,
'='
(t2) => t2.c1
})
.whereParentheses((sub) => sub
.whereNotExists(Table2, (subQuery, parentColumn) => {
subQuery.whereColumn((t2) => t2.c1, '=', parentColumn.c1)
})
.orWhere((t1) => t1.t2.c2, '=', 'valueThatUniquelyIdentifiesARow')
);
Here I am essentially having to recode the functionality of a left outer join despite already doing one
The outcome of the code above is:
row1: t1.c1, t2.c2
row2: t1.c1, t2.c2
row3 t1.c1, null
which is what you would get from the below sql code
Select t1.* , t2.*
From Table1 t1
Left Join Table2 t2 ON t1.c1 = t2.c1 And t2.c2 = 'valueThatUniquelyIdentifiesARow'
What I would like to be able to write in typed-knex:
typedKnex.query(Table1)
.innderJoinTableOnFunction('t2', Table2, (join) =>
join.onColumns(
(t1) => t1.c1,
'=',
(t2) => t2.c1,
'And',
(t2) => t2.c1,
'='
() => 'valueThatUniquelyIdentifiesARow'
)
);
Or Something like
typedKnex.query(Table1)
.leftOuterJoinTableOnFunction('t2', Table2, (join) =>
join.onColumns(
(t1) => t1.c1,
'=',
(t2) => t2.c1,
)
.whereColumn((t2) => t2.c2, '=', 'valueThatUniquelyIdentifiesARow'
);
The reason I'd like this change is because doing a where clause outside the join function understandably breaks the left outer join functionality by filtering out Table1
rows that don't have a corresponding Table2 join matching the unique value. It's a bit confusing, and the resulting whereParentheses
code is a bit unwieldy. I feel like I'm struggling to communicate what I mean so let me know if you want any clarification.
I don't know how hard this would be to do but it would be a nice update.
Hi, I think it makes sense for the join
object to support more than just .onColumns()
and .onNull()
Not sure if I can easily make it behave like a normal QueryBuilder object though.
I'll have a look this week and will report back 😄
Hey, same guy as the one who opened the issue, I looked in to your code and what knex does and it seems fairly straightforward to add the andOn()
functionality that knex already provides to your code. I went ahead and made a branch with those changes if you're interested in a pull request.
Hi, I checked out your code and wasn't quite sure if you wanted to compare a column or a value.
Knex.js has the undocumented onVal/andOnVal/orOnVal function to compare values.
So I added these and reworked onColumns to on/andOn/orOn.
Can you take a look at v2.9.0 to see if this does what you need?
Yea, i wanted to be able to do either columns or values as an additional clause for the joins. I think what you've done here is a good solution for that.
I gave the changes a go against my usecase and the andOnVal()
function works perfectly, thanks for the update!
Realized I need to get back on this account to close it, thanks for the update. You've got a really great library here.
Thanks!