Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

BlueDragon

MSSQL

Mensagens Recomendadas

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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."

 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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."

 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação 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

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.