wwwouter / typed-knex

A TypeScript wrapper for Knex.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!