GilZ
GilZ

Reputation: 6477

Select from an existing query in knex.js

I'm building a query using knex.js, given an existing sub query. Following this answer, and this thread in GitHub, I tried the following:

const knex = require("knex")({client: 'pg'});

const subQuery = knex.queryBuilder().select(1);

const query = knex.queryBuilder().select('*').from(subQuery);

console.log(query.toString());

But the result was:

select * from select 1

Which obviously has a syntax error. My expected result is:

select * from (select 1)

Why doesn't it add the parentheses, and how can I change it?

Upvotes: 3

Views: 9354

Answers (2)

GilZ
GilZ

Reputation: 6477

An ugly (but working) solution I found was using knex.raw and subQuery.toString:

const query = knex.queryBuilder()
    .select('*')
    .from(knex.raw(`(${subQuery})`);

I don't believe this is the best answer, and I'm sure I'm missing something, so I don't accept this answer yet.

Upvotes: 0

Mikael Lepistö
Mikael Lepistö

Reputation: 19718

Your way, how you did it seems correct and I would say that it is bug in knex why it doesn't work (I'm collaborator in knex).

Anyways there are couple of ways to do it...

const knex = require("knex")({client: 'pg'});

const subQuery = knex.select(1).as('t1');
const query = knex.select('*').from(subQuery);
console.log(query.toSQL());

{ method: 'select',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [],
  __knexQueryUid: '69d240ad-f5f8-4bc4-8c1d-fb9432af1da2',
  sql: 'select * from (select 1) as "t1"' }

Or you can use older style with function() subquery, which doesn't require .as(), but supports it...

const query = knex.select('*').from(sq => sq.select(1));
console.log(query.toSQL());

{ method: 'select',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [],
  __knexQueryUid: '31beb080-c89a-43b2-b112-546077330e82',
  sql: 'select * from (select 1)' }

Upvotes: 7

Related Questions