KnexJS如何创建多个内部联接

时间:2019-06-01 16:04:55

标签: sql database query-builder knex.js

我需要将此SQL查询转换为KnexJS查询

SELECT
    Book.Title,
    Book.Number,
    Author.Name,
    Author_1.Name,
    Author_2.Name,
    Author_3.Name
FROM
    ((((Book)
INNER JOIN Author ON Book.AuthName = Author.Name)
INNER JOIN Author AS Author_1 ON Book.AuthName = Author_1.Name)
INNER JOIN Author AS Author_2 ON Book.AuthName = Author_2.Name)
INNER JOIN Author AS Author_3 ON Book.AuthName = Author_3.Name
WHERE Book.Title = "HelpMe" ORDER BY Book.Number;

我已经在https://knexjs.org/#Builder-join中阅读了文档,但是我几乎不了解如何使用给定的示例来满足我的需要,因为没有针对此类多重内部联接的示例。

请帮助我

1 个答案:

答案 0 :(得分:0)

Knex连接是可链接的,因此您可以执行以下操作:

knex
  .select('title', 'author1', 'author2')
  .from('books')
  .join('authors as author1', 'books.author_name', '=', 'author1.name')
  .join('authors as author2', 'books.author_name', '=', 'author2.name')

我怀疑您的示例存在问题,因为您一次又一次地运行基本相同的比较。通常,您将使用一系列外键(authorsauthor1id)或更正确地联接表链接到author2id表,因为这是一个多对多关系:

knex
  .select('books.title', 'authors.name')
  .from('books')
  .join('books_authors', 'books.id', '=', 'books_authors.book_id')
  .join('authors', 'authors.id', '=', 'books_authors.author_id')

这会抓住这本书的所有作者,无论有多少作者,但都需要一个仅包含id的附加表:

exports.up = knex =>
  knex.schema.createTable('books_authors', t => {
    t.integer('book_id').references('books.id')
    t.integer('author_id').references('authors.id')
  })

exports.down = knex => knex.schema.dropTable('books_authors')

每次将作者添加到书中时,还应将书的ID和作者的ID添加到联接表中,以使两者之间存在关系。这样,每本书可以有一位作者或一百位作者。