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

BlueDragon

MSSQL

Recommended Posts

BlueDragon

Boas a todos,

Estou com um problema num select, que me anda a moer a cabeça.

A intenção é mostrar o nome de um vendedor e a percentagem de clientes que ele visitou num determinado periodo de tempo.

As visitas feitas nesse periodo de tempo são dadas através deste select:

SELECT        V.Name, COUNT(*) AS 'Contagem'
FROM            dbo.Clientes AS C INNER JOIN
                         dbo.Vendedores AS V ON C.SellerID = V.SellerID
GROUP BY V.Name

Depois tenho que juntar esse com:

SELECT        V.Name, COUNT(DISTINCT R.Cliente) * 100 /
                             ( AQUI FALTA O OUTRO SELECT) AS Percentagem
FROM            dbo.Vendedores AS V INNER JOIN
                         dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE        ((SELECT        DATEPART(Year, R.data) AS Expr1) LIKE '2010')
GROUP BY V.Name

Mas n está a dar, e estou sem ideias.

Se alguem conseguir ajudar fico agradecido

Share this post


Link to post
Share on other sites
TheDark

Devias ser mais explícito com o que é que "não está a dar", até porque não tens a 2ª query funcional.

Assim de repente, aquele SELECT dentro do WHERE não me parece bem. E o COUNT na Percentagem parece-me que deveria ser divisor, não dividendo.


Desaparecido.

Share this post


Link to post
Share on other sites
BlueDragon

boas,

ambos os selects tão funcionais, a junção dos dois é que dá raia, pois diz que o select que é divisor retorna mais que 1 resultado.

o outro select dentro do where está correctissimo. retorna apenas os registos que sejam de um determinado periodo de tempo.

quanto à conta:

Total de cliente neste mes / Total clientes * 100 = percentagem

Share this post


Link to post
Share on other sites
Tuntankamon

Se a contagem do primeiro SELECT é válida só tens de remover o V.Name da parte SELECT e inserir na clausula WHERE outra V2.SellerID = V.SellerID da query exterior para poder ficar tudo relacionado e só te devolver a contagem.

Como é óbvio terás de alterar o alias da query da contagem de V para V2

Share this post


Link to post
Share on other sites
BlueDragon

Boas,

Ja tinha testado dessa forma, mas verifica se é isto que tavas a sugerir.:

SELECT        V.Name, COUNT(DISTINCT R.Cliente) * 100 /
                             (SELECT        VV.Name, COUNT(*) AS 'Contagem'
                               FROM            dbo.Clientes AS C INNER JOIN
                                                         dbo.Vendedores AS VV ON C.SellerID = VV.SellerID
                               GROUP BY VV.Name) AS Percentagem
FROM            dbo.Vendedores AS V INNER JOIN
                         dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE        ((SELECT        DATEPART(Year, R.data) AS Expr1) LIKE '2010') AND (VV.SellerID = V.SellerID)
GROUP BY V.Name

sql.png

Share this post


Link to post
Share on other sites
TheDark

o outro select dentro do where está correctissimo. retorna apenas os registos que sejam de um determinado periodo de tempo.

Até pode funcionar, mas é completamente desnecessário. Além de estares a criar uma query extra, estás a obrigar o SGBD a converter entre int e varchar, e ainda a fazer um LIKE em vez de uma comparação simples entre inteiros. Podes fazer simplesmente WHERE DATEPART(YEAR, R.Data) = 2010.

quanto à conta:

Total de cliente neste mes / Total clientes * 100 = percentagem

Sim, eu percebi o que querias fazer. Não tinha era percebido que valores é que estavam em jogo.

Ja tinha testado dessa forma, mas verifica se é isto que tavas a sugerir.:

Não retiraste o VV.Name da subquery como disse o r00tfixxxer.


Desaparecido.

Share this post


Link to post
Share on other sites
BlueDragon

o group by?

sim tirei, não funcionou (o mesmo erro) depois ao copiar é que n copiei sem isso. Mas mesmo assim, se tirasse isso não estaria a devolver o que preciso, iria devolver o total de clientes existentes, e não o total de clientes do vendedor.

quanto à limitação por data tens razão.

Share this post


Link to post
Share on other sites
TheDark

o group by?

Não, da lista de colunas do SELECT. Deixa lá só o COUNT.


Desaparecido.

Share this post


Link to post
Share on other sites
BlueDragon

Nada, continua o mesmo erro...

Para alem disso, fora desse select ele n reconhece o VV.SellerID

...

Haverá uma maneira mais facil de fazer isto?

Share this post


Link to post
Share on other sites
M6

O VV.SellerID não é reconhecido porque o segundo VV.SellerID (que está no FROM da query principal) está fora do escopo.

O VV não é um alias conhecido no FROM da query principal, só é conhecido dentro do SELECT da query principal.

PS: esse (SELECT        DATEPART(Year, R.data) AS Expr1) LIKE '2010') não me parece que esteja ai a fazer, o que tu deves querer é DATEPART(Year, R.data) = 2010, mas posso estar errado...


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."

 

Share this post


Link to post
Share on other sites
BlueDragon

SELECT        V.Name, COUNT(DISTINCT R.Cliente) * 100 /
                             (SELECT        COUNT(*) AS 'Contagem'
                               FROM            dbo.Clientes AS C INNER JOIN
                                                         dbo.Vendedores AS VV ON C.SellerID = V.SellerID
                               GROUP BY VV.Name) AS Percentagem
FROM            dbo.Vendedores AS V INNER JOIN
                         dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE        (DATEPART(Year, R.data) = '2010')
GROUP BY V.Name

assim?

se for assim diz-me que o V.SellerId n está contico em nenhuma função agregadora,

se for:

SELECT        V.Name, COUNT(DISTINCT R.Cliente) * 100 /
                             (SELECT        COUNT(*) AS 'Contagem'
                               FROM            dbo.Clientes AS C INNER JOIN
                                                         dbo.Vendedores AS VV ON C.SellerID = VV.SellerID
                               GROUP BY VV.Name) AS Percentagem
FROM            dbo.Vendedores AS V INNER JOIN
                         dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE        (DATEPART(Year, R.data) = '2010')
GROUP BY V.Name

diz-me que a subquery devolve mais que um resultado...

Share this post


Link to post
Share on other sites
Tuntankamon

Isto está marado, não consigo postar o código...

Tive de postar com texto e depois Editar...

Aqui fica o que eu dizia, testa

SELECT V.Name, (COUNT(DISTINCT R.Cliente) * 100 /
                            (SELECT COUNT(*)
                             FROM  dbo.Clientes AS C INNER JOIN  dbo.Vendedores AS VV ON C.SellerID = VV.SellerID
                             WHERE VV.SellerID=V.SellerID)) AS Percentagem
FROM  dbo.Vendedores AS V INNER JOIN  dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE  (DATEPART(Year, R.data) = 2010)
GROUP BY V.Name

Share this post


Link to post
Share on other sites
BlueDragon

---------------------------

Microsoft Visual Studio

---------------------------

SQL Execution Error.

Executed SQL statement: SELECT V.Name, COUNT(DISTINCT R.Cliente) * 100 / (SELECT COUNT(*) AS Expr1 FROM dbo.Clientes AS C INNER JOIN dbo.Vendedores AS VV ON C.SellerID = VV.SellerID WHERE (VV.SellerID = V.SellerID)) AS Percentagem FROM dbo.Vendedores AS V INNER JOIN dbo.Rel...

Error Source: .Net SqlClient Data Provider

Error Message: Column 'dbo.Vendedores.SellerID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

---------------------------

OK  Ajuda 

---------------------------

eu tb tive que editar para poder postar...

Share this post


Link to post
Share on other sites
M6

Quando tens um group by tens de ter ai todas as colunas que não são agrupadas, ou seja todas as que não são counts, sums, etc..


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."

 

Share this post


Link to post
Share on other sites
BlueDragon

Boas,

E não é isso que está feito??

V.Name, o count n se mete, e sobra apenas o que é mostrado do select (As percentagem).

Se tiveres disponibilidade para uma ajuda remota por team viewer agradecia...

Share this post


Link to post
Share on other sites
BlueDragon

Resolvido,

deixo aqui para quem puder precisar de algo semelhante:



SELECT        V.Name, COUNT(DISTINCT R.Cliente) * 100 /
                             (SELECT        COUNT(C.ClientID) AS Expr1
                               FROM            dbo.Clientes AS C INNER JOIN
                                                         dbo.Vendedores AS VV ON C.SellerID = VV.SellerID AND VV.Name = V.Name) AS Percentagem 
FROM            dbo.Vendedores AS V INNER JOIN
                         dbo.Relatorios AS R ON V.SellerID = R.UserId
WHERE        (DATEPART(Month, R.data) = 5)
GROUP BY V.Name

a resolução estava no filtro VV.Name = V.Name, dentro da subquery. Isto tb poderia ser feito com o id.

Entretanto agradeço ao M6 e principalmente ao RootFixxer que tb esteve a tentar ajudar.

Share this post


Link to post
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

×

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.