2017-02-21 215 views
4

我试图创建子查询使用Knex以下查询:子查询的SELECT语句与Knex.js

SELECT 
    t.*, 
    (SELECT COUNT(*) FROM team_users tu WHERE TeamID = t.ID) AS UserCount, 
    (SELECT COUNT(*) FROM team_access ta WHERE TeamID = t.ID) AS AppCount 
FROM teams t WHERE OwnerUserID = _UserID; 

结果应该是球队的表从不同的表和USERCOUNT的AppCount计数聚合( team_users,team_access)

id | Name  | OwnerUserID | UserCount | AppCount 
----------------------------------------------------- 
134| Team A | 1538   | 7   | 6 
135| Team B | 1538   | 4   | 2 
136| Team C | 1538   | 12  | 1 

我想通是等效knex执行是:

var subquery1 = Knex.knex('team_users').count('*').where('TeamID', 'teams.ID').as('UserCount'); 
var subquery2 = Knex.knex('team_access').count('*').where('TeamID', 'teams.ID').as('AppCount'); 
Knex.knex.select('*', subquery1, subquery2).from('teams').where("OwnerUserID", ownerId).asCallback(dataSetCallback); 

运行时,我确实在返回的对象中得到了“UserCount”和“AppCount”列,但始终为零,可能是因为它没有在子查询中标识'teams.ID'。

我设法使用Knex.raw功能来解决这个问题:

Knex.knex('teams') 
    .select('*', Knex.knex.raw('(SELECT COUNT(*) FROM team_users WHERE TeamID = teams.ID) AS UserCount'), Knex.knex.raw('(SELECT COUNT(*) FROM team_access WHERE TeamID = teams.ID) AS AppCount')) 
    .where("OwnerUserID", ownerId) 
    .asCallback(dataSetCallback); 

,但我很想知道如何与子查询对象来实现这一目标。

回答

3

您试图通过teams.ID字符串作为值。为了能够做到.where('columnName', 'otherColumnName')必须使用knex.raw来通过otherColumnName作为标识符。

var teamsIdColumnIdentifier = knex.raw('??', ['teams.ID']); 

var subquery1 = Knex.knex('team_users').count('*') 
    .where('TeamID', teamsIdColumnIdentifier).as('UserCount'); 
var subquery2 = Knex.knex('team_access').count('*') 
    .where('TeamID', teamsIdColumnIdentifier).as('AppCount'); 

Knex.knex.select('*', subquery1, subquery2).from('teams') 
    .where("OwnerUserID", ownerId).asCallback(dataSetCallback);