How do I join two results of a query?

16

I'm developing an application in C # and would like to know how to merge two results from two queries into one. I have the following code:

public List<MalaDireta> ObterMalaDireta()
{    
    List<MalaDireta> resultado = new List<MalaDireta>();

    string sql_funcionario = "select id, nome, email from funcionario";
    string sql_fornecedor = "select id, nome, email from fornecedor";

    var conexao = new SqlConnection("string de conexão");

    var comando = new SqlCommand(sql_funcionario, conexao);

    try
    {
       conexao.Open();

       // como eu monto meu comando com as duas queries?

       var dataReader = comando.ExecuteReader();
       while (dataReader.Read())
       {
          MalaDireta m = new MalaDireta();
          m.Nome = dataReader["nome"];
          m.Email = dataReader["email"];

          resultado.Add(m);
       }
    }
    catch
    {
    }
    finally
    {
       conexao.Close();
    }

    return resultado;
}
    
asked by anonymous 11.12.2013 / 17:08

5 answers

21

How about joining through the sql query itself using UNION :

select id, nome, email from funcionario
union
select id, nome, email from fornecedor

In your case it would look like this:

string sql_todos = "select id, nome, email from funcionario " +
                   "union "+
                   "select id, nome, email from fornecedor";
    
11.12.2013 / 17:18
13

@Ecil's response is adequate, but I add the use of UNION ALL .

What is the difference between UNION and UNION ALL ?

  • UNION makes a kind of DISTINCT , inhibiting repeated results
  • UNION ALL brings all results, even those with repeated values

Is there any advantage in UNION ALL ? In theory, it is more efficient by not applying DISTINCT , that is, by not comparing the values of the registers.

So just a simple change:

string sql_todos = "select id, nome, email from funcionario " +
               "union all "+
               "select id, nome, email from fornecedor";

This concept applies at least to SQL Server, Oracle, MySQL and PostgreSQL.

    
19.12.2013 / 15:41
8

In theory, you just have to repeat the process of reopening the connection, running the other query, and passing the loopback by adding the results of your second query.

string sql_funcionario = "select id, nome, email from funcionario";
string sql_fornecedor = "select id, nome, email from fornecedor";

var conexao = new SqlConnection("string de conexão");


MalaDireta m = new MalaDireta();
var comando = new SqlCommand(sql_funcionario, conexao);

try
{
   conexao.Open();

   // como eu monto meu comando com as duas queries?

   var dataReader = comando.ExecuteReader();
   while (dataReader.Read())
   {

      m.Nome = dataReader["nome"];
      m.Email = dataReader["email"];

      resultado.Add(m);
   }
}
catch
{
}
finally
{
   conexao.Close();
}

var comando = new SqlCommand(sql_fornecedor, conexao);

try
{
   conexao.Open();

   // como eu monto meu comando com as duas queries?

   var dataReader = comando.ExecuteReader();
   while (dataReader.Read())
   {

      m.Nome = dataReader["nome"];
      m.Email = dataReader["email"];

      resultado.Add(m);
   }
}
catch
{
}
finally
{
   conexao.Close();
}
    
11.12.2013 / 17:25
5

There are two ways:

  • If the structure of your queries is the same you can use a UNION:
  • var query = "select id, nome, email from funcionario union select id, nome, email from fornecedor";

  • You can send the two queries in the same SqlCommand. The DataReader Class natively supports multiple results using the dataReader.NextResult() method:

        var comando = new SqlCommand(string.Concat(sql_funcionario, ";", sql_fornecedor), conexao);
        var dataReader = comando.ExecuteReader();
        while (dataReader.NextResult()) {
            while (dataReader.Read()) {
                MalaDireta m = new MalaDireta();
                m.Nome = dataReader["nome"];
                m.Email = dataReader["email"];
    
                resultado.Add(m);
            }
        }
    
  • 11.12.2013 / 18:07
    2

    Dear, even if some hidden magic can be put together to bring the two readers together for readability, I only see two options:

  • Put a union in the query and place the business logic next to the bank. (mean)
  • Take the two readers (converts to Enumerable entity) and merge with Linq, you can write Unit Tests to make the code responsible
  • 11.12.2013 / 17:16