【问题标题】:Sub-query in KnexKnex 中的子查询
【发布时间】:2014-05-05 14:57:03
【问题描述】:

我希望基本上在 Knex 中进行这种查询,但我无法让它工作:

select distinct *
from
(
  select *, 1 as rank from table1 where Word like 'mike'
  union
  select *, 2 as rank from table1 where Word like 'mike%'
  union
  select *, 3 as rank from table1 where Word like '%mike%'
) as X
order by WordOrder

我注意到一个类似的问题 here 并尝试遵循他们的建议,但似乎无法发现我的错误(或者如果这甚至是首先这样做的正确方法)。

var q = DB.knex('Users').select("*", "1 as rank").where("User", "like", query).
    union(function() {
        this.select("*", "2 as rank").where("User", "like", query + "%")
    }).
    union(function() {
        this.select("*", "3 as rank").where("User", "like", query + "%")
    });

DB.knex("Users").distinct("*").from('(' + q.toString() + ') as X').
    orderBy('rank').select().then(...)

如果有任何帮助,该特定查询会生成以下错误:

Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1`` order by `rank` asc' at line 1, sql: select distinct * from `select` as ``1`` order by `rank` asc, bindings: 

【问题讨论】:

    标签: knex.js


    【解决方案1】:

    编辑:此答案指的是旧版本的 knex。见other answer

    当我这样做时,我使用knex.raw 功能。您可以将任何原始 SQL 放在那里。像这样:

     var selectRaw = "SUM( IF( "+ table.id +" = 1, "+ table.value +", 0.00 )) as customAlias";
     query.column( knex.raw( selectRaw ) );
    

    您甚至可以使用 knex 构建查询,然后只需使用 .toString() 方法填充 knex.raw。我的示例不是他们 API 的一部分(那些 IFs...)。

    【讨论】:

    • 我最终做了类似的事情。我为每个联合选择创建了一个查询,对它们进行了字符串化,然后用它们构建了另一个查询。我想使用查询生成器的原因是它在清理输入方面做得很好。不想要任何注入攻击。
    • 另外,仅供参考,您现在可以在 0.6+ 中绑定原始语句中的参数,即使将它们插入到其他查询中,它也会保持正确的绑定
    • 我强烈建议让@tgriesser 的答案成为公认的答案,因为这反映了当今的现实。
    【解决方案2】:

    knex 0.6 版现在允许您在几乎任何地方使用子查询。在http://knexjs.org 的 chrome 控制台中弹出这个,你应该会看到它给了你想要的东西

    knex.distinct('*').from(function() {
      this.union(function() {
        this.select('*', '1 as rank').from('table1').where('Word', 'like', 'mike')
      }).union(function() {
        this.select('*', '2 as rank').from('table1').where('Word', 'like', 'mike%')
      }).union(function() {
        this.select('*', '3 as rank').from('table1').where('Word', 'like', '%mike%')
      })
      .as('X')
    }).orderBy('WordOrder').toString()
    

    【讨论】:

    • 谢谢!这或多或少是我最初想要的。
    • 我认为,这应该是公认的答案。谢谢@tgriesser!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多