Jump to content

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


Pedro Vieira

Recommended Posts

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
Link to comment
Share on other 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.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other 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?

Link to comment
Share on other 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)
10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Link to comment
Share on other 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..

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.