Select UNION + INNER JOIN

SQL

Delphi

19/11/2024

Preciso buscar 2 informações em 3 tabelas.

COD_FORNECEDOR
NOTA


Tabelas

PRE-NOTA
CONTAS_PAGAS
CONTAS_PAGAR


Para obter o COD_FORNECEDOR, preciso trazer também a tabela de FORNECEDORES, onde tenho disponível o CNPJ para fazer a pesquisa nesta tabela.

Hoje tenho apenas um UNION ALL que busca a NF

SELECT NOTA FROM PRE-NOTA
WHERE NOTA = :NF

UNION ALL

SELECT NOTA FROM CONTAS_PAGAR
WHERE NOTA = :NF

UNION ALL

SELECT NOTA FROM CONTAS_PAGAS
WHERE NOTA = :NF


Alguém sabe se é possivel fazer tudo na mesma consulta?
Renan

Renan

Curtidas 0

Melhor post

Arthur Heinrich

Arthur Heinrich

29/05/2025

Baseado no seu enunciado, acredito que a resposta do Alex seja bastante clara.

Entretanto, em relação à modelagem, farei algumas considerações.

O banco de dados precisa registrar os fatos da vida real, de uma maneira organizada.

Por exemplo, em uma relação comercial, envolvendo um fornecedor e um cliente, existe um produto ou serviço que fará parte de uma operação comercial.

Tudo o que ocorre, precisa de um documento relacionado, que vira um lançamento contábil.

Em uma venda de um produto ou serviço de um fornecedor para um cliente, ocorrem dois fatos: A entrega da mercadoria e a arrecadação do valor correspondente à compra. Embora a transação conte com estas duas etapas, elas são independentes.

Quando o fornecedor entrega o produto, ele precisa ser acompanhado de uma NF. É como se fosse um recibo de entrega do produto.
Quando o cliente efetua o pagamento, da mesma forma, é gerado um recibo deste pagamento.

Porém, esta relação não é 1:1 (um para um). Podemos ter entregas parciais ou pagamentos parcelados, incluindo multas e juros de mora.

Uma query misturar dados de venda (PRE-NOTA) com dados de pagamentos (CONTAS_PAGAR e CONTAS_PAGAS), é um sinal de que você está misturando bananas com laranjas (verdes e maduras).

Geralmente a venda gera uma NF, mas, dependendo da situação, precisamos de um documento de venda, que antecede a NF, para que o produto seja entregue parcialmente, sendo que a cada entrega, é gerada uma nova NF parcial, referente a cada entrega.

Já o recebimento, pode ser antecipado (produtos pré-pagos), à vista, à prazo ou parcelado. Pode inclusive ser dividido para pagamento em múltiplos meios de pagamento. Por exemplo, uma entrada à vista, em dinheiro, mais x parcelas no boleto.

Então, geralmente os relatórios não costumam misturar vendas com pagamentos, pois isso complica muito.

Também não faz muito sentido separar cobranças pagas de cobranças não pagas, a menos que seja por questões de performance ou IML (Information Lifecycle Management), onde você pode descartar dados para tornar o tamanho da base estável e controlar o desempenho das consultas.

Por exemplo, você pode ter uma tabela para registrar cobranças em aberto ou pagas nos últimos 30 dias, para efeito de relatórios. Mas, tudo o que já foi pago há mais de 30 dias, pode ser movido para uma tabela de histórico, para atender a exigências legais, ou mesmo para necessidade de reembolso. Passados 5 anos, os dados podem ser excluídos da base.

Embora rotinas de ILM sejam importantes para a saúde e custo operacional, nem sempre são implementadas ou necessárias, em função do volume de dados. Uma empresa pequena pode passar 10 anos com alguns milhares de documentos, enquanto outras, geram milhões por dia.
GOSTEI 1

Mais Respostas

Alex William

Alex William

19/11/2024

Olá, tudo bem?

Tente algo como:
SELECT f.COD_FORNECEDOR, foo.NOTA
FROM (
  SELECT CNPJ, NOTA FROM PRE-NOTA
  WHERE NOTA = :NF
 
  UNION ALL
 
  SELECT CNPJ, NOTA FROM CONTAS_PAGAR
  WHERE NOTA = :NF
 
  UNION ALL
 
  SELECT CNPJ, NOTA FROM CONTAS_PAGAS
  WHERE NOTA = :NF
) foo
INNER JOIN FORNECEDORES f ON f.CNPJ = foo.CNPJ


Seria mais ou menos isto, voce agrupa os resultados do UNION em um "foo" e ele trata o foo como uma tabela logica.

Espero ter ajudado :D
GOSTEI 0
POSTAR