我在SQL数据库工作了大约20年,似乎无法理解Knex映射查询的方式.有人可以帮我找到正确的代码吗?
我有这个SQL查询,我想在我的nodejs应用程序中使用:
SELECT p.id, p.project_number, p.project_name, p.start_date, p.end_date,
o.name, o.email_addr,
c.company, c.email_addr AS company_email, c.first_name, c.last_name
FROM projects p
INNER JOIN owners o ON o.id = p.owner_id
INNER JOIN clients c ON c.id = p.client_id
Run Code Online (Sandbox Code Playgroud)
KnexJS(0.7.5)文档显示了对我的查询看起来像这样的示例:
knex.from('projects').innerJoin('owners', 'owners.id', 'projects.owner_id')
.innerJoin('clients', 'clients.id', 'projects.client_id');
Run Code Online (Sandbox Code Playgroud)
我在文档中找不到几件事:
1)如何选择要包含的列?项目,客户和业主每个都有20到50列,我对所有这些都不感兴趣.从主表中选择列是明确的(使用select()或column())但是如何从连接表中选择列?
2)有些列具有相同的名称.如何避免名称冲突(即向其他表中的列添加一些前缀)?我查看了Knex可以生成列别名(... AS ...)的方式,我不确定它是否是更复杂查询的可行选项.(即使是像上面这样的相对简单的查询)
你可以试试:
knex('projects').select(['projects.id', 'projects.project_number', 'projects.project_name', 'projects.start_date', 'projects.end_date',
'owners.name', 'owners.email_addr as owner_email_addr',
'clients.company', 'clients.email_addr as client_email_addr', 'clients.first_name', 'clients.last_name'])
.innerJoin('owners', 'owners.id', 'projects.owner_id')
.innerJoin('clients', 'clients.id', 'projects.client_id');
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
在这个答案中,我将介绍更多内容,而不仅仅是选择和问题本身!
\n\n选择的原则是使用select。可以通过重命名列(别名)来避免名称冲突。\n要创建别名(列重命名),只需as在列名称字符串中使用,如下面的代码片段所示:
knex\n.select([\n \'table_a.id\',\n \'table_b.id as b_id\' // ---> the way to create aliases (to avoid \n]) // columns overlapping and overriding\n.from(\'table_a\')\n.leftJoin(\n \'table_b\',\n \'table_a.table_b_id\',\n \'table_b.id\'\n);\nRun Code Online (Sandbox Code Playgroud)\n\n它将生成以下 SQL:
\n\nSELECT \n "table_a"."id",\n "table_b"."id" as "b_id"\nFROM \n "table_a" \nLEFT JOIN "table_b" ON \n "table_a"."table_b_id" = "table_b"."id"\nRun Code Online (Sandbox Code Playgroud)\n\n我们可以用不同的方式来表述。一些有趣的如下:
\n\nknex(\'processes\') // <-- wihtout using from (shorter) [less sql like though]\n.select([ \n \'processes.id as processId\',\n \'processes.name as processName\',\n \'processes.description as processDescription\',\n \'processes.deleted as processDeleted\',\n \'processes.deleteTime as processDeleteTime\',\n \'rsp.runningSettingId\',\n \'rsp.value as settingValue\',\n \'rsp.startTime as settingStartTime\'\n])\n.innerJoin(\n \'runningSettings_processes as rsp\',\n \'processes.id\',\n \'rsp.processId\'\n);\nRun Code Online (Sandbox Code Playgroud)\n\nconst superJoinData = await knex( // i\'m using async await for the promises\n knex<Process>(\'process\')//__________________________from here\n .select([\n \'processes.id as processId\',\n \'processes.name as processName\', //--- conflict with rs.name\n \'processes.description as processDescription\', //-- conflict with rs.description\n \'processes.deleted as processDeleted\',\n \'processes.deleteTime as processDeleteTime\',\n \'rsp.runningSettingId\',\n \'rsp.value as settingValue\',\n \'rsp.startTime as settingStartTime\'\n ])\n .innerJoin(\n \'runningSettings_processes as rsp\',\n \'processes.id\',\n \'rsp.processId\'\n )//_______________________to here \n .as(\'prsp\') // |first join. (result an equivalent of a table)\n ) // !!!!!!!!!!!!!!!!! notice how we nested a knex construct within another!!\n .select([ // select from the resulting table of the first join !!!!\n \'prsp.processId\',\n \'prsp.processName\',\n \'prsp.processDescription\',\n \'prsp.processDeleted\',\n \'prsp.processDeleteTime\',\n \'prsp.runningSettingId\',\n \'prsp.settingValue\',\n \'prsp.settingStartTime\',\n \'rs.name as settingName\',\n \'rs.description as settingDescription\'\n ])\n .innerJoin( // ______________second inner join\n \'runningSettings as rs\',\n \'prsp.runningSettingId\',\n \'rs.id\'\n );\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n注意使用
\nas()方法!
使用 where 进行过滤:
\n\nknex(\n knex(\'A\').where(\'A.id\',1).as(\'t1\')\n).leftJoin(\n knex(\'B\').where(\'B.id\', 2).as(\'t2\'), \n \'t1.c\', \n \'t2.d\'\n)\n\n//or filter the resulting table of the join\nknex(\'A\')\n.leftJoin(\n knex(\'B\').where(\'B.id\', 2).as(\'t2\'), \n \'t1.c\', \n \'t2.d\'\n)\n.where(\'someColumn\', 2);\nRun Code Online (Sandbox Code Playgroud)\n\n使用回调进行进一步控制
\n\nknex\n.select(\'*\')\n.from(function () {\n this.select(\'*\').from(\'A\')\n .where(\'id\',1)\n .as(\'t1\');\n})\n.leftJoin(\n knex(\'B\').where(\'id\',2).as(\'t2\'), \n function () {\n this.on(\'t1.c\', \'=\', \'t2.d\'); // <--- notice also the use of function \n } // construct for the join condition\n);\nRun Code Online (Sandbox Code Playgroud)\n\n与上面相同,没有函数构造(并且具有多个连接条件作为奖励)
\n\nknex( // <--- notice the knex constructor (equivTo: knex.select().from())\n knex(\'A\') //NT: we already used that above when answering the question \n .select(\'*\')\n .where(\'id\',1)\n .as(\'t1\'); \n)\n.leftJoin(\n knex(\'B\').where(\'id\',2).as(\'t2\'), \n function () { // <----- notice that in place of using the 2nd and 3d arg, we can have a function in the 2nd arg\n this.on(\'t1.c\', \'=\', \'t2.d\').on(\'t1.s\', \'=\', \'t2.g\'); // <-----| \n } // plus: multiple on conditions______/\n);\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
7333 次 |
| 最近记录: |