Q:

Dúvida Query SQL - Consulta utilizando duas tabelas

estou com dúvidas em como fazer uma query. O problema é o seguinte:

Tenho duas tabelas semelhante as descritas abaixo (não tenho exatamente como elas eram, mas são próximas a representação abaixo):

Tabela 1 - Países
| País  | Empresa  |

|País A| Empresa 1|

|País A| Empresa 2|

|País A| Empresa 3|

|País B| Empresa 4|

|País B| Empresa 5|

|País C| Empresa 6|

Tabela 2 - Vendas
| Código | Vendedor | Comprador | Valor |

| 1      | Empresa 1| Empresa 5 | 100   |

| 2      | Empresa 1| Empresa 4 | 20    |

| 3      | Empresa 6| Empresa 2 | 120   |

| 4      | Empresa 5| Empresa 6 | 10    |

| 5      | Empresa 6| Empresa 1 | 200   |

| 6      | Empresa 4| Empresa 2 | 60    |

Na tabela 1 não há primary key. Na tabela 2 a coluna "código" é primary key. Todas as colunas das tabelas são varchar, exceto as colunas "código" e "valor".
O resultado deve ser uma tabela com os valores de compra e venda de cada país. Do tipo abaixo:
Tabela 3 - Resultado
| País | Vendas | Compras |

| País A | 120 | 280 |

| País B | 70 | 120 |

| País C | 220 | 10 |

Tentei escrever uma query que chegue a esse resultado, mas não consegui. Nas querys que fiz, o mais próximo que consegui foi a lista dos países, mas a soma não estava correta. Alguém poderia me ajudar com esse problema? Por favor.

A:

Uma forma que você tem de fazer é realizar subqueries para calcular a compra e a venda e depois utilizar um GROUP em conjunto com o SUM no resultado:
SELECT x.pais,
       SUM(x.vendas) AS vendas,
       SUM(x.compras) AS compras
FROM (
  SELECT p.pais,
         (SELECT SUM(v.valor)
            FROM vendas v
           WHERE v.vendedor = p.empresa) AS vendas,
         (SELECT SUM(v.valor)
            FROM vendas v
           WHERE v.comprador = p.empresa) AS compras
    FROM paises p
) x
GROUP BY x.pais;

Uma outra forma é realizar um CROSS JOIN e utilizar um CASE para verificar se naquela venda em questão há vinculo com o país:
SELECT p.pais,
       SUM(CASE v.vendedor WHEN p.empresa THEN v.valor ELSE 0 END) AS vendas,
       SUM(CASE v.comprador WHEN p.empresa THEN v.valor ELSE 0 END) AS compras
  FROM paises p
 CROSS JOIN vendas v
GROUP BY p.pais;

E há ainda uma terceira forma. Você pode realizar LEFT JOIN com a tabela vendas vinculando pelo vendedor e também pelo comprador e assim agrupar as informações somando com SUM:
SELECT p.pais,
       SUM(v1.valor) AS vendas,
       SUM(v2.valor) AS compras
  FROM paises p
  LEFT JOIN vendas v1 ON v1.vendedor = p.empresa
  LEFT JOIN vendas v2 ON v2.comprador = p.empresa
 GROUP BY p.pais

É necessário verificar o plano de execução para conferir qual a solução que custa menos para o banco de dados e que se aplica melhor ao seu cenário.

A:

Se eu entendi corretamente o seu problema, você precisaria fazer duas consultas para chegar neste resultado. A primeira consulta seria para montar a lista de empresas+pais  com as compras e vendas. Ficaria assim:
select P.Pais, P.Empresa,
(Select sum(valor) from Vendas where vendedor = P.Empresa) as vendas,
(Select sum(valor) from Vendas where comprador = P.Empresa) as compras
from Paises as P
GROUP BY P.Pais, P.Empresa

Sobre este resultado, você poderia fazer o agrupamento para montar a tabela por pais. Ficaria da seguinte forma:
Select Pais, sum(vendas) as vendas, sum(compras) as compras
from (
select P.Pais, P.Empresa,
(Select sum(valor) from Vendas where vendedor = P.Empresa) as vendas,
(Select sum(valor) from Vendas where comprador = P.Empresa) as compras
from Paises as P
GROUP BY P.Pais, P.Empresa
) tabela
GROUP BY Pais

