【问题标题】:How can I make a subquery with EXISTS on Knex?如何在 Knex 上使用 EXISTS 进行子查询?
【发布时间】:2021-10-28 22:12:27
【问题描述】:

我正在尝试使用 knex 构建查询,但在如何使用条件 EXISTS (SELECT * FROM caregiver_patient WHERE patient_id IN (0,1)) 实现“WHERE”部分时遇到了很多麻烦。

这是关于 SQL 的原始查询:

SELECT * FROM users 
    JOIN caregivers ON users.id = caregivers.user_id
    JOIN caregiver_schedule ON caregivers.id = caregiver_schedule.caregiver_id 
    JOIN caregiver_patient ON caregivers.id = caregiver_patient.caregiver_id
    JOIN patients ON caregiver_patient.patient_id = patients.id
    WHERE caregiver_schedule.week_day = 2
    AND caregiver_schedule.from_time <= 1320
    AND caregiver_schedule.to_time > 1320
    AND EXISTS (SELECT * FROM caregiver_patient WHERE patient_id IN (0,1));

这是我目前使用 Knex 的代码:

const caregivers = await db("caregivers")
  .whereExists(function () {
    this.select("caregiver_schedule.*")
      .from("caregiver_schedule")
      .whereRaw("`caregiver_schedule`.`caregiver_id` = `caregivers`.`id`")
      .whereRaw("`caregiver_schedule`.`week_day` = ??", [Number(week_day)])
      .whereRaw("`caregiver_schedule`.`from_time` <= ??", [timeInMinutes])
      .whereRaw("`caregiver_schedule`.`to_time` > ??", [timeInMinutes]);
  })
  .join("users", "caregivers.user_id", "=", "users.id")
  .join("patients", "caregiver_patient.patient_id", "=", "patients.id")
  .select([
    "caregivers.*",
    "users.*",
    "caregiver_schedule.*",
    "patients.*",
  ]);

原始查询中的所有数字都应该是变量。 IN 里面的数字应该是一个数组。

谁能帮我在 Knex 上完成这个查询?

【问题讨论】:

    标签: javascript sql node.js typescript knex.js


    【解决方案1】:

    您提供的示例 knex 查询与原始 SQL 查询完全不相似,如果您想将原始 SQL 查询转换为 knex 查询,这就是它的样子:

    const result = await db('users')
        .innerJoin('caregivers', 'users.id', 'caregivers.user_id')
        .innerJoin('caregiver_schedule', 'caregivers.id' 'caregiver_schedule.caregiver_id')
        .innerJoin('caregiver_patient', 'caregivers.id', 'caregiver_patient.caregiver_id')
        .innerJoin('patients', 'caregiver_patient.patient_id', 'patients.id')
        .where('caregiver_schedule.week_day', Number(week_day))
        .where('caregiver_schedule.from_time', '<=', timeInMinutes)
        .where('caregiver_schedule.to_time', '>', timeInMinutes)
        .whereExists(function() {
            this.select('*')
            .from('caregiver_patient')
            .whereIn('patient_id', [0,1]);
        })
        .select('*');
    
    

    这假定db 变量是您的knex 连接。我还不得不猜测你想用哪些变量来替换原始 SQL 中的硬编码值,你可以随意用任何你喜欢的变量替换。

    【讨论】:

    • 感谢您的回答!另外,您知道我如何确保内部选择上的选定寄存器仅与当前寄存器相关(看护者)例如,我想要这样的东西:AND EXISTS (SELECT * FROM caregiver_patient WHERE patient_id IN (1) AND caregiver_id=caregivers.user_id);我无法使用 knex
    • 您应该能够将另一个.where 粘贴到whereExists 函数内的上述查询中,唯一的区别是当您想在where 子句中引用另一列时,您需要使用稍微不同的语法,否则它将尝试匹配字符串文字 "caregivers.user_id" 而不是列。有两种方法可以做到这一点,第一种是使用 .ref ,例如.where('caregiver_id', knex.ref('caregivers.user_id'));,另一种选择是使用位置参数和 knex.raw 例如.where('caregiver_id', knex.raw('??', 'caregivers.user_id'));.
    猜你喜欢
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    相关资源
    最近更新 更多