點燈坊

失くすものさえない今が強くなるチャンスよ

如何 Inner Join 兩個 Table ?

Sam Xiao's Avatar 2021-10-22

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 最基本的功能。

join000

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。

join002

Conclusion

  • 若 inner join 需由兩個 field 綁定,則一定要傳入 callback,由多個 on 綁定 field

Reference

Knex, innerJoin