2016-03-22 39 views
10

Sto usando Sequelize nella mia app Express. Devo generare una query che abbia una sottoquery nella clausola WHERE.Sequelize - subquery in where clausola

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

ho provato relazioni/associazioni attraverso i miei modelli, ma non sono riuscito a farlo funzionare. Qualcosa di simile:

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 
    } ] 
}); 

Poi ho provato ad utilizzare Sequelize.where(), senza fortuna lì.

poi ho provato Sequelize.literal() e che le opere, ma non è sicuro se si tratta di una "propria" modo di fare una subquery in una clausola WHERE in Sequelize come io sono nuovo ad esso .

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

so anche che avrei potuto usare Sequelize.query() ma in realtà non so se devo raggiungere per esso o se literal() è il subito come mi sento come se ci fosse qualcosa che mi si affaccia.

Mi piacerebbe davvero sapere come eseguire una sottoquery in una clausola WHERE con Sequelize "corretto".

Grazie per il feedback!

+0

Guardando SO sono arrivato a questo problema github https://github.com/sequelize/sequelize/issues/3961, tramite questa domanda http://stackoverflow.com/questions/38882185/sequelize-statementwhere-in-statementwhere/39040218 # 39040218 e apparentemente utilizzando sequelize.literal è l'unico modo per il momento. – galileopy

+0

Sembra che usare 'sequelize.literal (...)' sia ancora la strada da percorrere –

+0

Ho trovato questo src che potrebbe aiutarti (NON TESTATO). fammi sapere del tuo test dopo aver seguito questo http://srlm.io/2015/02/04/sequelize-subqueries/ –

risposta

8

Ho riscontrato un problema simile nel mio progetto. Il modo in cui ho scelto per la sua attuazione è un po 'diverso per due ragioni:

  1. Se a un certo punto nel tempo Sequelize decide di attuare le query sub - la sintassi è pronto.
  2. Utilizzare Sequenza di protezione contro l'iniezione SQL.

Ecco lo snippet di codice, spero che sia d'aiuto.

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 + ')'), 
     } 
    } 
}); 

Alcune persone potrebbero scegliere di non utilizzare la variabile tempSQL e semplicemente costruire l'SQL all'interno della struttura find (magari usando un metodo di supporto?)

Penso anche che questo potrebbe essere la base per un sub query estensione per il sequelize in quanto utilizza quasi la stessa sintassi.