Inner Join 為 SQL 代表性功能,Knex 當然也支援,且提供多種寫法。
Version
Knex 0.20.13
Knex-fp 0.0.9
SQL
SELECT books.title, books.price, categories.name
FROM books
JOIN categories ON books.categoryId = categories.categoryId
WHERE categories.name = 'JS'
Inner join 是 SQL 最基本的功能。
Knex
import { map } from 'ramda'
import { format, log } from 'wink-fp'
mySQL ('books')
.select ('books.title', 'books.price', 'categories.name')
.innerJoin ('categories', 'books.categoryId', 'categories.categoryId')
.where ('categories.name', 'JS')
.then (map (format ('{title}/{name}: {price}')))
.then (log)
若 inner join 的條件只有一個 field,直接在 innerJoin
的第二個 argument 與第三個 argument 指定 field 即可。
import { map } from 'ramda'
import { format, log } from 'wink-fp'
mySQL ('books')
.select ('books.title', 'books.price', 'categories.name')
.innerJoin ('categories', x =>
x.on ('books.categoryId', 'categories.categoryId')
)
.where ('categories.name', 'JS')
.then (map (format ('{title}/{name}: {price}')))
.then (log)
innerJoin
的第二個 argument 也能傳入 callback,使用 x.on
綁定 field。
Knex-fp
import { pipeK, select, innerJoin, where } from 'knex-fp'
import { map } from 'ramda'
import { format, log } from 'wink-fp'
pipeK (
select ('books.title', 'books.price', 'categories.name'),
innerJoin ('categories', 'books.categoryId', 'categories.categoryId'),
where ('categories.name', 'JS')
) (
map (format ('{title}/{name}: {price}')),
log
) (mySQL ('books'))
也可從 Knex-fp 使用 innerJoin
,並使用 pipeK
組合 Knex function 與其他 synchronous function。
import { pipeK, select, innerJoin, on, where } from 'knex-fp'
import { map } from 'ramda'
import { format, log } from 'wink-fp'
pipeK (
select ('books.title', 'books.price', 'categories.name'),
innerJoin ('categories', on ('books.categoryId', 'categories.categoryId')),
where ('categories.name', 'JS')
) (
map (format ('{title}/{name}: {price}')),
log
) (mySQL ('books'))
若要在 innerJoin
傳入 callback,也能改用 on
使其 Point-free。
Conclusion
- 若 inner join 需由兩個 field 綁定,則一定要傳入 callback,由多個
on
綁定 field