Jump to content

MSSQL


BlueDragon
 Share

Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

http://img241.imageshack.us/img241/3618/sql.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

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

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

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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.

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
 Share

×
×
  • 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.