Ir para conteúdo

POWERED BY:

Arquivado

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

macielcr7

Select Complexo mysql

Recommended Posts

Olá tenho a tabela clientes...

 

com os seguintes campos

 

id_cliente | cliente_pai

 

e supondo que estejam cadastrados dessa forma no banco...

 

* Id Cliente => 1, Cliente Pai => 0

* Id Cliente => 2, Cliente Pai => 1

* Id Cliente => 3, Cliente Pai => 2

* Id Cliente => 4, Cliente Pai => 1

* Id Cliente => 5, Cliente Pai => 3

* Id Cliente => 6, Cliente Pai => 4

 

eu iria informar no select o ID do Cliente X

e então iria Buscar se o ID X existe no campo Cliente_pai

se existir eu pego o ID_CLIENTE e faço outra consulta para ver se ele tbm é cliente pai de outro cliente... e assim por diante...

 

Exemplo se eu informa ID do Cliente = 1;

 

ele ira buscar no cliente_pai e encontraria 2 ids de clientes, {2 e 4} depois q encontrase esse resultado eu iria fazer a mesma coisa com o 2 e depois com o cliente 4....

 

então iria me retornar dessa forma ID_CLIENTES => 2,4,3,6,5

 

Tem algum modo de fazer isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tudo na mesma query eu acredito que não. Você terá que fazer em 2 etapas:

 

-> Buscar os pais do o ID que você informou.

-> Então buscar os pais dos IDs que ele encontrou.

 

2 querys separadas, acredito eu.

 

Mas se você postar a estrutura básica da tabela eu posso dar uma tentada aqui pra você.

 

Abrass.

 

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

 

Tava pensando aqui agora no que você disse. Você quer apenas o último resultado? Ou o primeiro resultado você precisa armazenar pra algo? Se você precisar apenas do último, sendo o primeiro apenas uma conexão entre as duas querys dá de fazer.

 

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

 

Olha só:

 

SELECT C.ID_CLIENTE FROM CLIENTES AS C WHERE C.ID_CLIENTEPAI IN (SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1)

Sendo que 1 é o ID que você passou por parâmetro, no caso é uma variável. Só que com essa query você só pode retornar os dois últimos IDs.

 

Pra retornar 2,3,4 e 6 seria esta:

 

SELECT C.ID_CLIENTE FROM CLIENTES AS C WHERE C.ID_CLIENTEPAI IN (SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1)
UNION
SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1

 

E não sei de onde você buscou o 5 :P

 

Qualquer dúvida posta aí.

 

Abrass.

Compartilhar este post


Link para o post
Compartilhar em outros sites

acho q dar pra fazer com uma FUNCTION ou com PROCEDURE

 

fiz uma function assim mais nao sei ta dando erro...

CREATE FUNCTION Idcliente(ID INT)
RETURNS VARCHAR(255);
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
DECLARE sqls VARCHAR(255);
SET x = 0;
SET str = '';
if(x==0){
	SET sqls = 1;
}
             WHILE x < 100 DO
	if(x==0) SET @xs = SELECT id_cliente FROM `cliente` where cliente_pai = sqls;
               if(x==1) SET sqls = SELECT id_cliente FROM `cliente` where cliente_pai IN (xs);
	if(x>1) SET sqls = SELECT id_cliente FROM `cliente` where cliente_pai IN (sqls);
               SET  x = x + 1; 
	if NOT EXISTS(EXECUTE(sqls)){
	  RETURN sqls;
	}
             END WHILE;
END; 

#tambem Tentei dessa Forma Mais Nada.... Da erro 



CREATE FUNCTION `cliente`.`idCliente` (ID INT) RETURNS VARCHAR(255)
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
DECLARE sqls VARCHAR(255);
SET x = 0;
SET str = '';
SET sqls = ID;

   WHILE x < 100 DO
	case x
		when 0 then sqls = CONCAT('SELECT id_cliente FROM `cliente` where cliente_pai = ', sqls)
		when 1 then  sqls = CONCAT('UNION ALL', 'SELECT id_cliente FROM `cliente` where cliente_pai IN (',sqls,')')
		else sqls = CONCAT('UNION ALL', 'SELECT id_cliente FROM `cliente` where cliente_pai IN (',sqls,')')
	end;	                
	SET  x = x + 1;
	if NOT EXISTS(EXECUTE(sqls)){
		RETURN sqls;
	}
   END WHILE;
END;


Compartilhar este post


Link para o post
Compartilhar em outros sites

Não entendi a tua lógica cara...

 

Eu fiz uma tabela de teste aqui com o exemplo ali que você postou e consegui retornar 2,4,3 e 6. Tu quer procurar mais que duas vezes é isso? Vai acabar procurando a tabela toda...

 

Posta o "contexto" do que você tá querendo fazer, quem sabe a gente acha uma solução diferente pro que você precisa retornar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Note que você encontrou todos falta só o 5... é só fazer assim

SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1
UNION
SELECT C.ID_CLIENTE FROM CLIENTES AS C WHERE C.ID_CLIENTEPAI IN (SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1)
UNION
SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI IN (SELECT C.ID_CLIENTE FROM CLIENTES AS C WHERE C.ID_CLIENTEPAI IN (SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1))

 

Ou seja pega-se o SQL ANTERIOR e coloca dentro da CLAUSULA IN...

pra eu encontrar o resultado... eu queria usar uma function ou procedure....

 

e nela fazer um loop... e quando o SQL nao retornase resultado... e por q nao tem mais ClientePai...

entao eu sairia do LOOP

isso é o que eu tou tentando fazer...

na FUNCTION

Compartilhar este post


Link para o post
Compartilhar em outros sites

Huuuuuuuuuuuum agora eu entendi, você quer fazer um SELECT infinito até que não haja mais cliente pai.

 

Não seria mais fácil você dar um SELECT * FROM CLIENTES WHERE ID_CLIENTEPAI <> 0 ?

 

Se não for isso, fala se tu tem alguma outra regra de negócio pra ser aplicada na query que eu tento montar uma função pra ti.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá tenho a tabela clientes...

 

com os seguintes campos

 

id_cliente | cliente_pai

 

e supondo que estejam cadastrados dessa forma no banco...

 

* Id Cliente => 1, Cliente Pai => 0

* Id Cliente => 2, Cliente Pai => 1

* Id Cliente => 3, Cliente Pai => 2

* Id Cliente => 4, Cliente Pai => 1

* Id Cliente => 5, Cliente Pai => 3

* Id Cliente => 6, Cliente Pai => 4

 

eu iria informar no select o ID do Cliente X

e então iria Buscar se o ID X existe no campo Cliente_pai

se existir eu pego o ID_CLIENTE e faço outra consulta para ver se ele tbm é cliente pai de outro cliente... e assim por diante...

 

Exemplo se eu informa ID do Cliente = 1;

 

ele ira buscar no cliente_pai e encontraria 2 ids de clientes, {2 e 4} depois q encontrase esse resultado eu iria fazer a mesma coisa com o 2 e depois com o cliente 4....

 

então iria me retornar dessa forma ID_CLIENTES => 2,4,3,6,5

 

Tem algum modo de fazer isso?

 

 

nao é isso que você fez....

vou tentar falar da function....

CREATE FUNCTION `cliente`.`idCliente` (ID INT) RETURNS VARCHAR(255)
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
DECLARE sqls VARCHAR(255);
SET x = 0;
SET str = '';
SET sqls = ID;

   WHILE x < 100 DO
	case x
		when 0 then SET sqls = CONCAT('SELECT id_cliente FROM `cliente` where cliente_pai = ', sqls)
		when 1 then  SET sqls = CONCAT('UNION ALL', 'SELECT id_cliente FROM `cliente` where cliente_pai IN (',sqls,')')
		else SET sqls = CONCAT('UNION ALL', 'SELECT id_cliente FROM `cliente` where cliente_pai IN (',sqls,')')
	end;	                
	SET  x = x + 1;
	if NOT EXISTS(EXECUTE(sqls)){
		RETURN sqls;
	}
   END WHILE;
END;

 

quando x = 0;

ele vai fazer um concat..

que retornará o resultado abaixo....

SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI = 1

aii eu seto X+1;

e depois eu execulto o SQL...

na codição

IF NOT EXISTS(Execute(sqls)){return sqls;}

 

ou seja se nao existir mais registros... ele irá me retorna a string sqls ; formatada pra eu fazer a consulta....

 

quando x > 0 ele ja pega o SQL ANTERIOR...

e coloca dentro do IN...

 

SELECT L.ID_CLIENTE FROM CLIENTES AS L WHERE L.ID_CLIENTEPAI IN (SQL_ANTERIOR)

 

Deu pra entender?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi, mas tu já pensou nas consequências? Vai chegar uma hora que vai ter milhares de IN dentro um do outro. Mas beleza, me dá um tempo que eu tento fazer a tal FUNCTION...

Compartilhar este post


Link para o post
Compartilhar em outros sites

OBS.: Peço um pouco de paciência pois só poderei dar uma olhada nessa função mais tarde com mais tempo e calma. Abrass.

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.