Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alias a table in Knex

I have a SQL query that refers to the same table twice, and I need to alias the table to two separate aliases. I can't quite figure out how to compose this with Knex.

There's a 'Words' table and a 'Users' table. The Words table has two foreign keys, 'author_id' and 'winner_id', referencing the Users table's 'id' column.

Here's the SQL I'm trying to compose in Knex:

SELECT w.*, ua.name, uw.name FROM Words AS w INNER JOIN Users AS ua ON w.author_id = ua.id  LEFT JOIN Users AS uw ON w.winner_id = uw.id 

I'm a little lost as to how to do this in Knex. My first attempt didn't involve aliasing, and so I got a 'table used more than once' error. When I tried to use the .as() method, knex complained that there was a missing .from() clause. Is the .as() method only used for aliasing subqueries, and I shouldn't expect it to be used to alias tables?

like image 885
Bobby Circle Ciraldo Avatar asked Feb 06 '15 01:02

Bobby Circle Ciraldo


2 Answers

I think I figured it out. In knex.js, say you specify a table like:

knex.select( '*' ).from( 'Users' )

Then you can just add the AS keyword within the quotes of the table name to alias it, like so:

knex.select( '*' ).from( 'Users AS u' )

..and you can do this for column names, too; so my original SQL would look like this in knex-land:

    knex.select( 'w.*', 'ua.name AS ua_name', 'uw.name AS uw_name' )     .innerJoin( 'Users AS ua', 'author_id', 'ua.id' )     .leftJoin( 'Users as uw', 'winner_id', 'uw.id' ) 

I guess I got confused by the presence of knex's .as() method, which (as far as I currently understand) is meant just for subqueries, not for aliasing tables or column names.

like image 193
Bobby Circle Ciraldo Avatar answered Sep 19 '22 13:09

Bobby Circle Ciraldo


There are two ways to declare an alias for identifier (table or column). One can directly give as aliasName suffix for the identifier (e.g. identifierName as aliasName) or one can pass an object { aliasName: 'identifierName' }.

So, the following code:

 knex.select('w.*', 'ua.name', 'uw.name')   .from({ w: 'Words' })   .innerJoin({ ua: 'Users' }, 'w.author_id', '=', 'ua.id')   .leftJoin({ uw: 'Users' }, 'w.winner_id', '=', 'uw.id')   .toString() 

will compile to:

select "w".*, "ua"."name", "uw"."name" from "Words" as "w" inner join "Users" as "ua" on "w"."author_id" = "ua"."id" left join "Users" as "uw" on "w"."winner_id" = "uw"."id" 
like image 30
Евгений Евдокимов Avatar answered Sep 19 '22 13:09

Евгений Евдокимов