2016-03-22 2 views
10

Я использую Sequelize в своем экспресс-приложении. Мне нужно сгенерировать запрос с подзапросом в предложении WHERE.Sequelize - подзапрос в том, где статья

SELECT * 
    FROM MyTable 
WHERE id NOT IN (
     SELECT fkey 
     FROM MyOtherTable 
     WHERE field1 = 1 
      AND field2 = 2 
      AND field3 = 3 
     ) 

я впервые попробовал отношения/ассоциации через свои модели, но не мог заставить его работать. Что-то вроде:

MyTable.find({ 
    where: { 
     id: { 
      $notIn: // <= what goes here? Can I somehow reference my include model? 
     } 
    }, 
    include: [ { 
     model: MyOtherTable, 
     where: { 
      field1: 1, 
      field2: 2, 
      field3: 3 
    } ] 
}); 

Затем я попытался с помощью Sequelize.where(), не повезло там.

Затем я попытался Sequelize.literal() и что работает, но не уверен, если это «правильный» способ сделать подзапрос в котором положение в Sequelize, как я новичок в этом.

MyTable.find({ 
    where: { 
     id: { 
      $notIn: sequelize.literal( 
       '(SELECT fkey ' + 
        'FROM MyOtherTable ' + 
        'WHERE field1 = ' + field1 + 
        ' AND field2 = ' + field2 + 
        ' AND field3 = ' + field3 + 
       ')' 
     } 
    } 
}); 

Я также знаю, что я мог бы использовать Sequelize.query(), но на самом деле не знаю, если я должен тянуться к нему, или если literal() это право далеко, как я чувствую, что есть что-то я с видом.

Мне очень хотелось бы знать, как выполнить подзапрос в предложении WHERE с Sequelize «надлежащий» способ.

Благодарим вас за отзыв!

+0

Глядя на СО, я пришел к этой проблеме github https://github.com/sequelize/sequelize/issues/3961 через этот вопрос http://stackoverflow.com/questions/38882185/sequelize-statementwhere-in-statementwhere/39040218 # 39040218, и, по-видимому, использование sseelize.literal - единственный способ на данный момент. – galileopy

+0

Кажется, что использовать 'sequelize.literal (...)' все еще путь –

+0

Я нашел этот src, который может вам помочь (UNTESTED). сообщите мне о своем тесте после того, как вы последуете этому http://srlm.io/2015/02/04/sequelize-subqueries/ –

ответ

8

Я столкнулся с аналогичной проблемой в своем проекте. Путь я выбираю реализовать немного отличается по двум причинам:

  1. Если в один момент времени Sequelize решает осуществить подзапросы - синтаксис готов.
  2. Использовать защиту от повторного включения SQL-инъекций.

Вот мой фрагмент кода, надеюсь, что это поможет.

const tempSQL = sequelize.dialect.QueryGenerator.selectQuery('MyOtherTable',{ 
    attributes: ['fkey'], 
    where: { 
     field1: 1, 
     field2: 2, 
     field3: 3 
    }}) 
    .slice(0,-1); // to remove the ';' from the end of the SQL 

MyTable.find({ 
    where: { 
     id: { 
      $notIn: sequelize.literal('(' + tempSQL + ')'), 
     } 
    } 
}); 

Некоторые люди могут выбрать, чтобы не использовать переменную tempSQL и просто строить SQL внутри структур находят (возможно, используя вспомогательный метод?)

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

Смежные вопросы