• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Pedro Vieira

[SQL SERVER] Registos não aparecem devido a falta de dados em outra consulta

6 mensagens neste tópico

Bom dia. .

Eu estou com um problema numa query deste gênero : por exemplo quero listar todos os clientes juntamente com as suas vendas de 2008 e vendas de 2009.

Faço 1 select à tabela clientes e 2 vezes à tabela de vendas para poder filtrar os anos.

Algo assim

|-------|  |----------| |----------|

|Clientes|  |  Vendas |  |Vendas (1)|

|          |  |            |  |              |

|--------| |----------| |----------|

O problema é que se existir um cliente que não tenha registo de vendas em 2008 não aparece. e eu necessito que apareça . .

Se ajudar a query é esta:


SELECT dbo.Entidades.No_, dbo.Entidades.[Nome Completo], dbo.Entidades.limitcredportal AS credatrc, dbo.Entidades.limitcred AS credatrcnav, dbo.Entidades.[customer posting group] AS mercado, dbo.aux_credito.vendas AS vendasb, dbo.aux_credito.ano, SUM(dbo.saldocli.saldo) AS saldo, aux_credito_1.vendas AS vendasc, dbo.controlodecredito.havecredit, dbo.controlodecredito.consultardaf, dbo.controlodecredito.embarcar, dbo.controlodecredito.segurocredito as segcred, dbo.Entidades.segcred as segcrednav, dbo.Entidades.termpag as prazonav, dbo.Entidades.metodopag as formapagamentonav, dbo.controlodecredito.prazoacordado as prazo, dbo.controlodecredito.formapagamento, CONVERT(varchar, dbo.controlodecredito.revistoem,102) as revistoem , CASE WHEN ISNUMERIC(SUBSTRING(dbo.controlodecredito.prazoacordado, 1, LEN(dbo.controlodecredito.prazoacordado) - 1))= 1 THEN -dbo.aux_credito.vendas / 365 * CONVERT(INT, SUBSTRING(dbo.controlodecredito.prazoacordado, 1, LEN(dbo.controlodecredito.prazoacordado) - 1)) ELSE 0 END AS [credito estimado] 
FROM dbo.Entidades LEFT OUTER JOIN dbo.aux_credito AS aux_credito_1 ON dbo.Entidades.No_ = aux_credito_1.codcli LEFT OUTER JOIN dbo.aux_credito ON dbo.Entidades.No_ = dbo.aux_credito.codcli LEFT OUTER JOIN dbo.saldocli ON dbo.Entidades.No_ = dbo.saldocli.ncli LEFT OUTER JOIN dbo.controlodecredito ON dbo.Entidades.No_ = dbo.controlodecredito.idCli 
GROUP BY dbo.Entidades.No_,dbo.Entidades.limitcredportal, dbo.Entidades.limitcred, dbo.Entidades.[Nome Completo], dbo.aux_credito.vendas, dbo.aux_credito.ano, aux_credito_1.ano, aux_credito_1.vendas, dbo.Entidades.segcred, dbo.Entidades.termpag, dbo.Entidades.[customer posting group], dbo.controlodecredito.havecredit, dbo.controlodecredito.consultardaf, dbo.controlodecredito.embarcar, dbo.controlodecredito.segurocredito, dbo.Entidades.metodopag, dbo.controlodecredito.revistoem, dbo.controlodecredito.prazoacordado, dbo.controlodecredito.formapagamento 
HAVING (dbo.aux_credito.ano = 2008) AND (aux_credito_1.ano = 2009) 
ORDER BY vendasb asc

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não consegui compreender bem a tua query mas fiquei com a clara sensação de que não necessitas de fazer left outer join duas vezes com a tabela aux_credito.

Dada a complexidade da coisa, o melhor é dividir isso e ir por partes.

Por exemplo, começar por seleccionar os clientes e depois juntar as vendas e verificar se os dados obtidos estão correctos, e por fim juntar as vendas e confirmar de novo que os dados obtidos estão correctos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu creio que precisava de uma referencia cruzada, a minha query está mais complicada porque tenho mais algumas consultas mas é algo deste genero:

SELECT     dbo.Entidades.[Nome Completo], dbo.aux_credito.ano, dbo.aux_credito.vendas
FROM         dbo.Entidades INNER JOIN
                      dbo.aux_credito ON dbo.Entidades.No_ = dbo.aux_credito.codcli
WHERE     (dbo.aux_credito.ano = 2008 OR
                      dbo.aux_credito.ano = 2009)

Mas assim aparece-me duas linhas por cada cliente, então eu peguei e acrescentei outra consulta que no fundo é a mesma para poder ter numa linha os dois anos:

SELECT     dbo.Entidades.[Nome Completo], dbo.aux_credito.ano, dbo.aux_credito.vendas, aux_credito_1.ano AS anodoismilnove, 
                      aux_credito_1.vendas AS vendasdoismilnove, dbo.Entidades.No_
FROM         dbo.Entidades LEFT OUTER JOIN
                      dbo.aux_credito AS aux_credito_1 ON dbo.Entidades.No_ = aux_credito_1.codcli LEFT OUTER JOIN
                      dbo.aux_credito ON dbo.Entidades.No_ = dbo.aux_credito.codcli
WHERE     (dbo.aux_credito.ano = 2008) AND (aux_credito_1.ano = 2009)

Mas com essa query os clientes que não tenham vendas num dos anos indicados por exemplo 2008 , não aparecem. Eu gostaria que em vez disso me aparecesse 0 no lugar das vendas 2008.

Fiz me entender?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se tens linhas iguais é porque te falta um filtro no cruzamento, no limite podes usar select distinct para eliminar os duplicados, e esse segundo cruzamento é desnecessário.

Se necessitas de transformar linhas em colunas, podes fazer o select dentro do select, exemplo:

SELECT dbo.Entidades.[Nome Completo], 
'2008',
( select sum(vendas)
from dbo.aux_credito 
  where dbo.Entidades.No_ = dbo.aux_credito.codcli 
and dbo.aux_credito.ano = 2008) as vendas2008,
'2009',
( select sum(vendas)
from dbo.aux_credito 
  where dbo.Entidades.No_ = dbo.aux_credito.codcli 
and dbo.aux_credito.ano = 2009) as vendas2009
FROM         dbo.Entidades 
LEFT OUTER JOIN
                      dbo.aux_credito AS aux_credito_1 ON dbo.Entidades.No_ = aux_credito_1.codcli 
WHERE     (dbo.aux_credito.ano = 2008) AND (aux_credito_1.ano = 2009)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hum ;) gostei, muito obrigado. Apenas uma coisa mais, como faço agora para utilizar o valr vendas2008 para fazer contas no mesmo select por exemplo.

SELECT dbo.Entidades.[Nome Completo], 
'2008',
( SELECT sum(vendas)
FROM dbo.aux_credito 
  WHERE dbo.Entidades.No_ = dbo.aux_credito.codcli 
AND dbo.aux_credito.ano = 2008) AS vendas2008,
'2009',
( SELECT sum(vendas)
FROM dbo.aux_credito 
  WHERE dbo.Entidades.No_ = dbo.aux_credito.codcli 
AND dbo.aux_credito.ano = 2009) AS vendas2009, (vendas2008+vendas2009) as total 

Ele diz que nao reconhece a coluna vendas 2008 nem vendas 2009

EDIT: Já está :) já está tudo a funcionar direito ;P Muito obrigado. . . coloquei novamente

( SELECT sum(vendas)
FROM dbo.aux_credito 
  WHERE dbo.Entidades.No_ = dbo.aux_credito.codcli 
AND dbo.aux_credito.ano = 2008)

para fazer os filtros e afins...

Cumprimentos..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora