Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

KleuToN´s

[Resolvido] Consulta Sql, Como não repetir JOIN

Recommended Posts

Amigos do iMasters, eu tenho a seguinte consulta:

$busca = "SELECT d.id, d.nome, d.usuario, d.dep, c.nome, c.valor, DATE_FORMAT( d.data, '%d/%m/%Y' ), d.status

FROM TABELA_DADOS_USER AS d

LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id

LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO AS c ON a.id_cat = c.id "

 

Que retorna algo assim:

relatorioj.jpg

 

Existe a possibilidade desse usuário com Cod. (3) dfsd não repetir? mesmo ele tendo 2 associações diferentes?

 

Agradeço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

um modo simples é remover o join e usar um sub select.

inclusive o relacionamento entre A e C pode ser feito usando join dentro do subselect

 

 

obs: isso não é a solução definitiva, tampouco é a melhor.. é apenas uma alternativa

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro gostaria de agradecer a ajuda, hinom.

Fiquei na duvida como Remover um Join se preciso dos 3, explicando melhor:

-> JOIN TABELA_DADOS_ASSOCIACAO - AS ( A )

Nessa tabela é cadastra mais de uma associação, que um usuário pode der porém o nome da associação e valor, são de outra tabela que cadastra esses nomes e valores dinamicamente.

-> TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO - AS ( C )

Esse contém esse nome e valor dos tipos de Associações existentes

 

Tipo se eu remover do JOIN a Tabela ( C ) fico sem receber o Dado NOME e VALOR que é pego do id_use da Tabela (A) onde pode conter mais de uma associação.

Já se eu remover a Tabela (A) fico sem receber tudo que é reverente a Associação do USER.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tenta isso:

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 -- nome e valor na mesma coluna
 GROUP_CONCAT(CONCAT(c.nome, '(', c.valor, ')') SEPARATOR ', ') as associacoes
 -- somente nome
 -- GROUP_CONCAT(c.nome SEPARATOR ', ') as associacoes
 DATE_FORMAT( d.data, '%d/%m/%Y' ),
 d.status
FROM TABELA_DADOS_USER AS d
LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id
LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIACAO AS c ON a.id_cat = c.id
GROUP BY d.id

 

@braços e fique com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tenta isso:

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 -- nome e valor na mesma coluna
 GROUP_CONCAT(CONCAT(c.nome, '(', c.valor, ')') SEPARATOR ', ') as associacoes
 -- somente nome
 -- GROUP_CONCAT(c.nome SEPARATOR ', ') as associacoes
 DATE_FORMAT( d.data, '%d/%m/%Y' ),
 d.status
FROM TABELA_DADOS_USER AS d
LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id
LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIACAO AS c ON a.id_cat = c.id
GROUP BY d.id

 

@braços e fique com Deus!

 

Amigo esses quote funcionou perfeitamente!! Show, só tem um pequeno erro faltou a virgula depois do as associacoes, colgando ele funciona na hora!

Me veio outras duvidas, se poder ajudar agradeço.

1ª - posso usar o

.number_format($dados[5], 2, ',', '.');
para pegar o valor em forma de real R$, dentro da consulta ?

2ª - Essa tabela TABELA_DADOS_ASSOCIACAO também tem status, posso definir para Não apresentar quando tiver d.status=N por exemplo.

3ª - é algo diferente e eu acho a Pior, tipo como posso fazer um consulta para pegar somente os usuários sem associação ou melhor os NULL veja nessa imagem abaixo, para que a pessoa que estar usando o sistema saber que tem que cadastra Associações para esse que estão sem, entende?

rekatorio.jpg

Deste já agradeço, Estejam com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

1. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_format

2. crie uma condicional WHERE field = ...

3. pode usar uma condicional WHERE ou a função HAVING()

Amigo relacionado ao 2. pos usar WHERE dentro do GROUP_CONCAT ou no final do SELECT, é porque na verdade não entendi como pegar um WHERE de Join ?

Exemplo WHERE field = a.id_use num dar certo, ou seria um WHERE field = com JOIN, é uma viagem isso! rsrs desculpem a ignorância.

Relacionado ao 3. No Google não encontrei muita coisa sobre a função HAVING(), teria um link de algo próximo?

 

Grato

Compartilhar este post


Link para o post
Compartilhar em outros sites

não entendi como pegar um WHERE de Join ?

SELECT 
field
FROM tb1 AS A
LEFT JOIN tb2 AS B ON a.id = b.id
WHERE
tb1.id < 100

 

No Google não encontrei muita coisa sobre a função HAVING()

há vasto material no google... procure em ingles, chinês, etc..

http://lmgtfy.com/?q=mysql+HAVING

 

veja exemplos e explanações da própria documentação:

http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html

Compartilhar este post


Link para o post
Compartilhar em outros sites

WHERE é para uma condição "de linha"

 

SELECT ID,SUM(VALOR) VALOR
FROM COMPRAS
WHERE VALOR > 100
GROUP BY ID

 

Somar, por clientes as vendas > que $100

 

HAVING é para "grupo"

 

 

SELECT ID,SUM(VALOR) VALOR
FROM COMPRAS
GROUP BY ID
HAVING VALOR > 100

 

Somar, por cliente, e listar aqueles cuja soma total for > $100

Compartilhar este post


Link para o post
Compartilhar em outros sites

não entendi como pegar um WHERE de Join ?

SELECT 
field
FROM tb1 AS A
LEFT JOIN tb2 AS B ON a.id = b.id
WHERE
tb1.id < 100

 

No Google não encontrei muita coisa sobre a função HAVING()

há vasto material no google... procure em ingles, chinês, etc..

http://lmgtfy.com/?q=mysql+HAVING

 

veja exemplos e explanações da própria documentação:

http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html

 

Realmente procurei no Google só tem coias de outro país, isso nem é o pior..mais pelo pouco que entendo sobre a função HAVING() ela é tipo uma função de contagem, como por exemplo mostra dados duplicado em uma tabela, isso realmente serve para mim? estou sem entender.

Eu nem sei se para isso preciso de JOINS, eu pensei em faze if (condições) mais não deu certo, pois preciso saber o que de uma ligação JOIN não tenho na outra tabela, tipo o que na tabela B não tem na tabela A em ligação.

 

Dessa Maneira retorna vazio

SELECT d.id, d.nome, d.usuario, d.dep, a.id, DATE_FORMAT( d.data, '%d/%m/%Y' ), d.status

FROM d_a AS d

LEFT JOIN d_ass AS a ON a.id_use = d.id

WHERE a.id < 0

 

Dessa maneira Também retorna vazio:

SELECT d.id, d.nome, d.usuario, d.dep, a.id, DATE_FORMAT( d.data, '%d/%m/%Y' ), d.status

FROM d_a AS d

LEFT JOIN d_ass AS a ON a.id_use = d.id

HAVING a.id < 0

 

Sendo que se eu colocar o ( a.id>0 ) Retorna os valores de todos que possuem ligação com a tabela d_ass , já se eu remover o ( HAVING a.id>0 ) ou (WHERE a.id < 0 ) vem todos os valores com ou sem ligação, mais preciso só dos que não tem essa ligação como na seleção da imagem abaixo:

null.png

Compartilhar este post


Link para o post
Compartilhar em outros sites

em alguns casos utilizo HAVING também com subselect, independente de estar usando GROUP:

 

HAVING(SELECT COUNT(id) FROM table WHERE column > 100) > 20

 

obs: não quer dizer que seja para o seu caso específico.

Compartilhar este post


Link para o post
Compartilhar em outros sites

3ª - é algo diferente e eu acho a Pior, tipo como posso fazer um consulta para pegar somente os usuários sem associação ou melhor os NULL veja nessa imagem abaixo, para que a pessoa que estar usando o sistema saber que tem que cadastra Associações para esse que estão sem, entende?

 

Kleuton,

 

Para retornar onde a `associação` é NULL, uma das maneiras é trabalhar com o statement EXISTS.

 

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 DATE_FORMAT( d.data, '%d/%m/%Y' ) AS data,
 d.status
FROM TABELA_DADOS_USER AS d
WHERE EXISTS (SELECT * FROM TABELA_DADOS_ASSOCIACAO AS a WHERE a.id_use = d.id AND a.id_cat IS NULL)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Kleuton,

 

Para retornar onde a `associação` é NULL, uma das maneiras é trabalhar com o statement EXISTS.

 

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 DATE_FORMAT( d.data, '%d/%m/%Y' ) AS data,
 d.status
FROM TABELA_DADOS_USER AS d
WHERE EXISTS (SELECT * FROM TABELA_DADOS_ASSOCIACAO AS a WHERE a.id_use = d.id AND a.id_cat IS NULL)

 

amigo você entendeu bem o que preciso pensei q iria funcionar, porém reportou o seguinte erro:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS d WHERE EXISTS (SELECT * FROM d_ass AS a WHERE a.id_use = d.id AND a.id_cat I' at line 8

 

estar parecendo q seja a versão mysql,

Meu servidor Localhost:

Apache 2.2.11

PHP 5.3.5

MySql 5.5.8

Compartilhar este post


Link para o post
Compartilhar em outros sites

$busca = "

 

select id,nome_a,usuario,dep,group_concat(nome_B) cargos,sum(valor) valor_total,max(dia) dia

(

SELECT d.id, d.nome_a, d.usuario, d.dep, c.nome nome_b, c.valor, DATE_FORMAT( d.data, '%d/%m/%Y' ) dia, d.status

FROM TABELA_DADOS_USER AS d

LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id

LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO AS c ON a.id_cat = c.id

)z

group by id,nome_a,usuario,dep

";

 

 

embora o codigo acima gere o resultado que voce deseja, suas tabelas devem estar rompendo as regras de normalizaçao...

Compartilhar este post


Link para o post
Compartilhar em outros sites

amigo você entendeu bem o que preciso pensei q iria funcionar, porém reportou o seguinte erro:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS d WHERE EXISTS (SELECT * FROM d_ass AS a WHERE a.id_use = d.id AND a.id_cat I' at line 8

 

estar parecendo q seja a versão mysql,

Meu servidor Localhost:

Apache 2.2.11

PHP 5.3.5

MySql 5.5.8

Kleuton, está dando erro de sintaxe. No entanto, a sintaxe da query que postei está correta.

Poste a query completa, que está dando este erro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Kleuton, está dando erro de sintaxe. No entanto, a sintaxe da query que postei está correta.

Poste a query completa, que está dando este erro.

 

Segue:

SELECT d.id, d.nome, d.usuario, d.dep, a.id, a.id, DATE_FORMAT( d.data,  '%d/%m/%Y' ), d.status
FROM d_a AS d
WHERE EXISTS (SELECT * d_ass AS a WHERE a.id_use=d.id AND a.id_cat IS NULL)

 

Usando Join também apresenta o mesmo erro:

SELECT d.id, d.nome, d.usuario, d.dep, a.id, a.id, DATE_FORMAT( d.data,  '%d/%m/%Y' ), d.status
FROM d_a AS d
LEFT JOIN d_ass AS a ON a.id_use = d.id
LEFT JOIN d_cat AS c ON a.id_cat = c.id 
WHERE EXISTS (SELECT * d_ass AS a WHERE a.id_use=d.id AND a.id_cat IS NULL)

 

Lembando:

TABELA_DADOS_USER = d_a

TABELA_DADOS_ASSOCIACAO = d_ass

TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO = d_ass

 

Amigos deste já agradeço imensamente o empenho dos que me ajudam, isso e estar me dando uma dor de cabeça, mais estou aprendendo muito mesmo!

Vou dormir... hehehe o sono pegou, de manhã inicio mais teste!

 

$busca = "

 

select id,nome_a,usuario,dep,group_concat(nome_B) cargos,sum(valor) valor_total,max(dia) dia

(

SELECT d.id, d.nome_a, d.usuario, d.dep, c.nome nome_b, c.valor, DATE_FORMAT( d.data, '%d/%m/%Y' ) dia, d.status

FROM TABELA_DADOS_USER AS d

LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id

LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO AS c ON a.id_cat = c.id

)z

group by id,nome_a,usuario,dep

";

 

 

embora o codigo acima gere o resultado que voce deseja, suas tabelas devem estar rompendo as regras de normalizaçao...

 

Amigo Giesta, não entendi sua forma de SELECT, bem como tem colunas que nao existem na minha tabela ex: nome_a nome_b, o servidor me reportou o seguinte erro:

 

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cargos,sum(valor) valor_total,max(dia) dia ( SELECT d.id, d.nome_a, d.usuario, d' at line 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Segue:

SELECT d.id, d.nome, d.usuario, d.dep, a.id, a.id, DATE_FORMAT( d.data,  '%d/%m/%Y' ), d.status
FROM d_a AS d
WHERE EXISTS (SELECT * d_ass AS a WHERE a.id_use=d.id AND a.id_cat IS NULL)

 

Usando Join também apresenta o mesmo erro:

SELECT d.id, d.nome, d.usuario, d.dep, a.id, a.id, DATE_FORMAT( d.data,  '%d/%m/%Y' ), d.status
FROM d_a AS d
LEFT JOIN d_ass AS a ON a.id_use = d.id
LEFT JOIN d_cat AS c ON a.id_cat = c.id 
WHERE EXISTS (SELECT * d_ass AS a WHERE a.id_use=d.id AND a.id_cat IS NULL)

 

Lembando:

TABELA_DADOS_USER = d_a

TABELA_DADOS_ASSOCIACAO = d_ass

TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIAÇÃO = d_ass

Kleuton, está faltando o FROM no SELECT do EXISTS.

 

WHERE EXISTS (SELECT * FROM d_ass AS a WHERE a.id_use=d.id AND a.id_cat IS NULL)

Compartilhar este post


Link para o post
Compartilhar em outros sites

com base na consulta que lhe enviei:

1ª - posso usar o para pegar o valor em forma de real R$, dentro da consulta ?

 

Eu faria no PHP, no MySQL, sem stored procedures suas, o mais perto (e menos complicado) que conheço é esse:

CONCAT('R$',FORMAT(c.valor,2))

 

2ª - Essa tabela TABELA_DADOS_ASSOCIACAO também tem status, posso definir para Não apresentar quando tiver d.status=N por exemplo.

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 GROUP_CONCAT(CONCAT(c.nome, '(', c.valor, ')') SEPARATOR ', ') as associacoes,
 DATE_FORMAT( d.data, '%d/%m/%Y' ),
 d.status
FROM TABELA_DADOS_USER AS d
LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id
LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIACAO AS c ON a.id_cat = c.id
WHERE d.status <> 'N'
GROUP BY d.id

 

3ª - é algo diferente e eu acho a Pior, tipo como posso fazer um consulta para pegar somente os usuários sem associação ou melhor os NULL veja nessa imagem abaixo, para que a pessoa que estar usando o sistema saber que tem que cadastra Associações para esse que estão sem, entende?

SELECT 
 d.id, 
 d.nome,
 d.usuario,
 d.dep,
 GROUP_CONCAT(CONCAT(c.nome, '(', c.valor, ')') SEPARATOR ', ') as associacoes,
 DATE_FORMAT( d.data, '%d/%m/%Y' ),
 d.status
FROM TABELA_DADOS_USER AS d
LEFT JOIN TABELA_DADOS_ASSOCIACAO AS a ON a.id_use = d.id
LEFT JOIN TABELA_DADOS_COM_NOME_E_VALOR_DA_ASSOCIACAO AS c ON a.id_cat = c.id
WHERE c.nome IS NULL 
GROUP BY d.id

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ricci ottadnot, valeu mesmo ao empenho sua ajuda foi importante, porém mesmo depois da inclusão do From o resultado retorna vazio!

 

Amigo hufersil venho informar que ficou perfeito a consulta Sql funcionou com sucesso, mui grato!!!

Tópico resolvido !

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.