Я хочу сделать такой запрос в 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

Я заметил аналогичную проблему здесь и попытался последовать их совету, но не могу обнаружить свою ошибку (или если это вообще правильный способ сделать это в первую очередь).

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: 
17
Salem 27 Мар 2014 в 02:03

2 ответа

Лучший ответ

Knex версии 0.6 позволяет использовать подзапросы практически где угодно. Вставьте это в консоль Chrome по адресу http://knexjs.org, и вы увидите, что он дает вам то, что вы ищете.

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()
36
kyrisu 25 Сен 2017 в 17:26
Спасибо! Это более или менее то, что я изначально искал.
 – 
Salem
25 Июн 2014 в 19:48
4
Я думаю, это должен быть принятый ответ. Спасибо @tgriesser!
 – 
Pierre Spring
24 Сен 2015 в 15:38

Изменить: этот ответ относится к более старой версии knex. См. другой ответ.

Когда я это делаю, я использую функцию 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 (эти IF ...).

3
Community 23 Май 2017 в 15:02
Я закончил тем, что сделал что-то подобное. Я создал запрос для каждого из этих объединенных выборок, преобразовал их в строку, а затем построил из них еще один запрос. Причина, по которой я хотел использовать построитель запросов, заключалась в том, что он хорошо очищает ввод. Не хочу никаких инъекционных атак.
 – 
Salem
1 Апр 2014 в 02:39
Кроме того, просто к вашему сведению, теперь вы можете привязывать параметры в необработанных операторах в 0.6+, даже когда они интерполируются в другие запросы, он поддерживает правильные привязки.
 – 
tgriesser
25 Июн 2014 в 09:14
2
Я настоятельно рекомендую сделать ответ @tgriesser принятым, так как это то, что отражает реальность в наши дни.
 – 
Pierre Spring
24 Сен 2015 в 15:37