尝试使用knex和where子句中的嵌入式select构建复杂的查询

时间:2019-10-17 20:22:59

标签: mysql knex.js

我正在尝试将以下SQL查询转换为knex:

SELECT A.sid,
        A.rid,
        A.dataset_name,
        A.jobname,
        A.ndmjob,
        A.ndmprocess,
        A.programs,
        A.version,
        A.backup_dataset,
        A.fxrnum,
        A.`type`,
        A.destination,
        A.frequency,
        A.snode,
        A.runtask,
        A.clientDSN,
        A.comments
    FROM filedesigner.fileSpecification A
    WHERE A.file_id = var_fileid AND
          A.version = (
     SELECT MAX(B.version) 
       FROM filedesigner.fileSpecification B
      WHERE B.sid = A.sid
        AND B.version <= var_version)
    ORDER BY A.rid DESC, 
             A.dataset_name;

我目前在我的knex查询解析器中拥有此功能:

this.db
      .select(
        'A.sid as specId',
        'A.version',
        'A.rid',
        'A.dataset_name as datasetName',
        'A.jobname as jobName',
        'A.ndmjob as ndmJob',
        'A.ndmprocess as ndmProcess',
        'A.backup_dataset as backupDataset',
        'A.programs',
        'A.fxrnum as fxrNum',
        'A.type',
        'A.destination',
        'A.frequency',
        'A.snode',
        'A.runtask',
        'A.clientDSN',
        'A.comments'
      )
      .from('fileSpecification as A')
      .where('file_id', fileId)
      .andWhere('version', () => this.db
        .max(
          'B.version'
        )
        .from('fileSpecification as B')
        .where('A.sid', 'B.sid')
        .andWhere('B.version', '<=', version)
        .then(data => data[0]))
      .orderBy('sid', 'asc')
      .orderBy('version', 'desc')
      .orderBy('rid', 'desc')
      .orderBy('dataset_name', 'asc')
      .cache(ttl)
      .then(data => data);

但是我收到此错误的结果是:(变量为fileId = 33和version ='2.0.1')

select `A`.`sid` as `specId`, `A`.`version`, `A`.`rid`, `A`.`dataset_name` as `datasetName`, `A`.`jobname` as `jobName`, `A`.`ndmjob` as `ndmJob`, `A`.`ndmprocess` as `ndmProcess`, `A`.`backup_dataset` as `backupDataset`, `A`.`programs`, `A`.`fxrnum` as `fxrNum`, `A`.`type`, `A`.`destination`, `A`.`frequency`, `A`.`snode`, `A`.`runtask`, `A`.`clientDSN`, `A`.`comments` from `fileSpecification` as `A` where `file_id` = 33 and `version` = (select *) order by `sid` asc, `version` desc, `rid` desc, `dataset_name` asc - ER_NO_TABLES_USED: No tables used

我尝试了几种变体,它们都给我相同的结果,或更糟的是。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

尽管没有示例数据很难测试,但这是您的SQL的Knex转换:

const version = db
  .max("B.version")
  .from("filedesigner.fileSpecification as B")
  .where("B.sid", "A.sid")
  .andWhere("B.version", "<=", var_version);

db.select(
  "A.sid",
  "A.rid",
  "A.dataset_name",
  "A.jobname",
  "A.ndmjob",
  "A.ndbprocess"
  // etc
)
  .from("filedesigner.fileSpecification as A")
  .where("A.file_id", var_fileid)
  .andWhere("A.version", version)
  .orderBy([{ column: "A.rid", order: "desc" }, "A.dataset_name"])
  .then(console.log)
  .catch(console.error)

请注意,子查询上没有.then调用。您将其留给Knex来管理...您根本不想等待承诺。我在结尾处留了一个console.log,以使其在.then的去处更加明显。