[英]How to tranform a SQL query to a KnexJS function with a joining function
我正在尝试将 PSQL 中的以下查询转换为 KnexJS
SELECT
sum("current")
FROM (
SELECT
"study_id",
"site_id",
"status",
max("day") AS "day"
FROM
"candidates"
WHERE
"study_id" in('TBX1')
AND "status" in('INCOMPLETE')
GROUP BY
"study_id",
"site_id",
"status") AS "latest"
INNER JOIN "candidates" ON "latest"."day" = "candidates"."day"
AND "latest"."study_id" = "candidates"."study_id"
AND ("latest"."site_id" = "candidates"."site_id" or
("latest"."site_id" is null and "candidates"."site_id" is null))
AND "latest"."status" = "candidates"."status";
直到这一点我才能得到,但我错过了与 NULL 比较的查询部分,我不知道如何将它添加到我的 Knex 函数中
const group = [columns.studyId, columns.siteId, columns.status];
const filterFn = this.filter;
const x = this.tx
.sum(selectColumn)
.from(function subQuery() {
this.select(group).max(columns.day, { as: 'day' }).from(tableName).groupBy(group).as('latest');
filterFn.call({ builder: this }, filter);
})
.join(tableName, function joinOn() {
[columns.day, ...group].map(column =>
this.on(`latest.${column}`, `${tableName}.${column}`).on(
this.tx.raw(`("latest"."site_id" = "candidates"."site_id" or
("latest"."site_id" is null and "candidates"."site_id" is null))`)
)
);
})
join 方法正在创建我的连接,但没有 NULL 比较,我错过了原始查询中的这部分
AND ("latest"."site_id" = "candidates"."site_id" or
("latest"."site_id" is null and "candidates"."site_id" is null))
无法理解如何添加最后一部分来完成我的查询功能
棘手的一点看起来是因为您只想要site_id
列的连接的null
部分,但目前它包含在map
函数调用中,因此每次循环都会应用。 处理它的一种方法是为site_id
所需的特殊情况添加if
语句。 IE
const group = [columns.studyId, columns.siteId, columns.status];
const filterFn = this.filter;
const x = this.tx
.sum(selectColumn)
.from(function subQuery() {
this.select(group).max(columns.day, { as: 'day' }).from(tableName).groupBy(group).as('latest');
filterFn.call({ builder: this }, filter);
})
.join(tableName, function () {
[columns.day, ...group].map(column => {
if (column === 'site_id') {
this.on(function () {
this.on(`latest.${column}`, `${tableName}.${column}`)
.orOn(function () {
this.onNull(`latest.${column}`)
.onNull(`${tableName}.${column}`);
});
});
} else {
this.on(`latest.${column}`, `${tableName}.${column}`);
}
});
})
我无法完全重新创建您的案例,因为我无权访问您的filterFn
。 但是没有那个我从上面使用console.log(x.toString())
得到的 sql 最终是
select sum(`current`)
from (
select
`study_id`,
`site_id`,
`status`,
max(`day`) as `day`
from
`candidates`
group by `study_id`,
`site_id`,
`status`) as `latest`
inner join `candidates` on `latest`.`day` = `candidates`.`day`
and `latest`.`study_id` = `candidates`.`study_id`
and (`latest`.`site_id` = `candidates`.`site_id` or
(`latest`.`site_id` is null and `candidates`.`site_id` is null))
and `latest`.`status` = `candidates`.`status`
看起来像您所追求的(假设您的filterFn
添加了所需的where
子句)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.