Q: Consulta mysql com subquery em NodeJs Tenho a seguinte estrutura nas seguintes tabelas.
parceiro (idParceiro, nome, email, telefone) exemplo
parceiroTag (idParceiro, tag)
O que eu preciso fazer, um select na tabela parceiro e fazer um for no resultado e consultar a tabela parceiroTag pelo idParceiro e trazer os resultados para preencher um Json que fique dessa forma.


[{
  nome: 'nome teste',
  email: 'email teste',
  telefone: 1199999999,
  tags: ['tag1', 'tag2', 'tag3']
}, {
  nome: 'nome teste',
  email: 'email teste',
  telefone: 1199999999,
  tags: ['tag1', 'tag2', 'tag3']
}]


O problema é que quando eu consulto a primeira tabela e faço um for no resultado para pegar o ID e ir na outra tabela ele se perde por ser async.
Como posso resolver isso no NODE.JS pois tenho varias consultas que dependem de outra para gerar um Json.
Segue abaixo meu código.


router.route('/parceiro').get(function(req, res) {
  parceiro.consultar(req, function(err, rows){
    if(err) return res.status(400).json(err);

    var p  = [];
    _.each(rows, function(one) {
      var pa = {};
      pa.parceiroId = one.parceiroId;
      pa.clienteId = one.clienteId;
      pa.nome = one.nome;
      pa.imagemDestaque = one.imagemDestaque;
      pa.imagemLogo = one.imagemLogo;
      pa.desconto = one.desconto;
      pa.titulo = one.titulo;
      pa.descricao = one.descricao;
      pa.urlSite = one.urlSite;
      pa.validadeDe = one.validadeDe;
      pa.validadeAte = one.validadeAte;
      pa.isCupom = one.isCupom;
      pa.urlOferta = one.urlOferta;
      pa.cupomDesconto = one.cupomDesconto;
      pa.ativo = one.ativo;
      pa.dataCadastro = one.dataCadastro;
      pa.tags = [];
      parceiro.tag(req, function(err, r){
        _.each(r, function(two) {
          pa.tags.push(two.tag);
        });
      });
      pa.categorias = [];
      pa.regioes = [];
      p.push(pa);
    });
    return res.status(200).json(p);
  });
});



A: Uma outra abordagem, ainda melhor que fazer isso no Node.js é fazer essa junção de dados no MySQL.
Assim podes concatenar as tags com o GROUP_CONCAT e receber isso nas colunas das row que o MySQL retorna, sem teres de fazer várias queries para ir buscar "pedaços" da informação.
Testa assim:
SELECT p.id, p.nome, GROUP_CONCAT(t.tag) AS tags FROM parceiro AS p
INNER JOIN parceiroTag AS t ON p.id = t.parceiroid
GROUP BY id

Exemplo aqui (link).

A: Precisas encadear essa lógica para só chamares o res.status().json() quando esse objeto tiver todas as propriedades que precisas. E como tudo é assícrono a coisa complica um pouco.
Um biblioteca boa para trabalhar esses encadeamentos, chama-se async. Mas fazendo "à mão" acho que precisas de algo assim:
function waitForIt(obj, tables, done) {
    var callbacks = 0;
    return function(err) {
        if (err) return console.log(err);
        callbacks++;
        if (callbacks == tables.length) done(err, obj);
    }
}

function join(table, obj, cb) {
    parceiro[table](req, function(err, r) {
        obj[table] = r.map(function(row) {
            return row.tag;
        });
        cb(err);
    });
}

router.route('/parceiro').get(function(req, res) {
    parceiro.consultar(req, function(err, rows) {
        if (err) return res.status(400).json(err);
        rows.forEach(function(pa) {
            var cb = waitForIt(pa, ['tag', 'regi'], function(err, obj) {
                if (err) return res.status(400).json(err);
                return res.status(200).json(obj);
            });
            tables.forEach(function(table) {
                join(table, pa, cb);
            });
        });
    });
});

A ideia é chamar as tabelas todas que precisas, juntar ao objeto o que a tabela traz e depois, só quando todas as callbacks das subqueries tiverem sido chamadas; só então chamar a ultima callback a que dei nome de done.
Notas: 


*

*#1 fiz o código agora, não testei, mas é éssa a lógica que precisas.    

*#2 ainda acho que dava para fazer isso só com MySQL :)

*#3 usar if (err) return res.status(400).json(err); vai expôr ao utilizador erros internos da aplicação e pode gerar falhas na segurança da BD.


A: Consegui fazer da seguinte forma.


exports.consultar  = function (req, callback) {
  req.getConnection(function(err,connection){
    connection.query('SELECT * FROM parceiro', function(err, result){
      done = _.after(result.length, function () {
        callback(err, result)
      });
      result.forEach(function(pa){
        connection.query('SELECT * FROM parceiroTag where parceiroId = ' + pa.parceiroId, function(err, result){
          pa.tags = [];
          for (var i = 0; i < result.length; i++) {
            pa.tags.push(result[i].tag);
          }
          done();
        });
      });
    });
  });
};


Obrigado pela ajuda de todos.
