Select com GROUP ou INNER JOIN ????

03/12/2015

Boa Noite,
tenho a Seguinte Tabela: tb_teste
[img:descricao=tb_teste]http://arquivo.devmedia.com.br/forum/imagem/466315-20151203-214335.png[/img]
Segue o Codigo pra Criar a Mesma se Necessario:
CREATE TABLE IF NOT EXISTS `tb_teste` (
`id` int(11) NOT NULL,
  `nivel` int(11) DEFAULT NULL,
  `id_resp` int(11) DEFAULT NULL,
  `tipo_resp` text,
  `nome` text
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=71 ;

--
-- Extraindo dados da tabela `tb_teste`
--

INSERT INTO `tb_teste` (`id`, `nivel`, `id_resp`, `tipo_resp`, `nome`) VALUES
(50, 3, 0, 'D', 'Teste A'),
(51, 2, 0, 'D', 'Teste B'),
(52, 3, 0, 'D', 'Teste B'),
(53, 2, 0, 'D', 'Teste B'),
(54, 3, 53, 'F', 'Teste B'),
(55, 3, 0, 'D', 'Teste F'),
(56, 2, 51, 'F', 'Teste G'),
(57, 3, 67, 'F', 'Teste H'),
(58, 3, 51, 'F', 'Teste I'),
(59, 3, 53, 'F', 'Teste j'),
(60, 2, 53, 'F', 'Teste K'),
(61, 3, 60, 'F', 'Teste L'),
(62, 3, 0, 'D', 'Teste M'),
(63, 3, 53, 'F', 'Teste N'),
(64, 3, 60, 'F', 'Teste O'),
(65, 2, 67, 'F', 'Teste P'),
(66, 3, 60, 'F', 'Teste Q'),
(67, 2, 60, 'F', 'Teste R'),
(68, 3, 51, 'F', 'Teste S'),
(69, 3, 53, 'F', 'Teste T'),
(70, 3, 67, 'F', 'Teste U');


ALTER TABLE `tb_teste`
 ADD PRIMARY KEY (`id`);


conforme podem observar cada id tem um id_responsavel ex: a Id 69 o id_resp = 53,

situação preciso listar dos que são nivel 2 desde que o id_resp = 53, isso é facil seria o seguinte codigo:

SELECT `id`, `nivel` FROM `tb_teste` WHERE `nivel`=2 and `id_resp`=53 


Isto me retornaria o Id = 60

Porém eu gostaria de buscar tambem os nivel 2 que estão relacionado ao 53 alem do id 60, e assim por diante, obsevando que o ID 60 é id_resp do id 67 e o 67 é id_resp do 65


ou seja eu gostaria de consultar os nivel 2 nos quais o id_resp inicial seja 53, me retornando em uma unica consulta as ids 60,67,65

não tenho a minima ideia de como realizar esta consulta. sem usar um for - while no PHP vazendo varios selects

esta foi uma tentativa

SELECT id, nivel
FROM
  tb_teste
Where  nivel=2 and (id_resp=53 OR id_resp IN
(SELECT id
FROM
  tb_teste
Where  nivel=2 and id_resp=53))


retorno :


| id | nivel |
|----|-------|
| 60 |     2 |
| 67 |     2 |

Dyosse

Melhor resposta

04/12/2015

A partir do id_resp 53, você quer selecionar todos os descendentes dele que tenham o nivel = 2...

53
 +-60
    +-67
       +-65 


SELECT t1.id as id_root, t2.id as id_nivel1, t3.id as id_nivel2, t4.id as id_nivel3
FROM tb_teste t1 LEFT JOIN tb_teste t2 on (t1.id = t2.id_resp and t2.nivel = 2)
                 LEFT JOIN tb_teste t3 on (t2.id = t3.id_resp and t3.nivel = 2)
                 LEFT JOIN tb_teste t4 on (t3.id = t4.id_resp and t4.nivel = 2)   
WHERE t1.id = 53  

É isso ?

Marcos P

Responder Citar

Outras Respostas

03/12/2015

Dyosse

Segunda tentativa:

SELECT id, nivel
FROM
  tb_teste
Where  nivel=2 and id_resp=53 OR (id_resp IN
(SELECT id
FROM
  tb_teste
Where  nivel=2) and nivel=2) 

retorno:
| id | nivel |
|----|-------|
| 56 |     2 |
| 60 |     2 |
| 65 |     2 |
| 67 |     2 |


nesse retorno quase deu certo porem o id 56 nao pertece a nenhuma id_resp vinculado ao id 53 :( x,(
Responder Citar

04/12/2015

Dyosse

Muito Obrigado , mas é quase Isso!!!


@Marcos P SELECT t1.id as id_root, t2.id as id_nivel1, t3.id as id_nivel2, t4.id as id_nivel3 FROM tb_teste t1 LEFT JOIN tb_teste t2 on (t1.id = t2.id_resp and t2.nivel = 2) LEFT JOIN tb_teste t3 on (t2.id = t3.id_resp and t3.nivel = 2) LEFT JOIN tb_teste t4 on (t3.id = t4.id_resp and t4.nivel = 2) WHERE t1.id = 53


este codigo que vc fez, me retorna o resultado em colunas e me limita somente a ate três descendentes abaixo, tenho uma situação que vai ate 15 descendentes RS!

mas temos uma bom inicio, eu to pesquisando aqui,

se eu for fazer da forma qcomo me colocou eu teria que ter algo assim:

SELECT t1.id as id_root, t2.id as id_nivel1, t3.id as id_nivel2, t4.id as id_nivel3, t5.id as id_nivel4, t6.id as id_nivel5, t7.id as id_nivel6, t8.id as id_nivel7, t9.id as id_nivel8, t10.id as id_nivel9, t11.id as id_nivel10, t12.id as id_nivel11, t13.id as id_nivel12, t14.id as id_nivel13, t5.id as id_nivel14
FROM tb_teste t1 LEFT JOIN tb_teste t2 on (t1.id = t2.id_resp and t2.nivel = 2)
                 LEFT JOIN tb_teste t3 on (t2.id = t3.id_resp and t3.nivel = 2)
                 LEFT JOIN tb_teste t4 on (t3.id = t4.id_resp and t4.nivel = 2)   
                 LEFT JOIN tb_teste t5 on (t4.id = t5.id_resp and t5.nivel = 2) 
                 LEFT JOIN tb_teste t6 on (t5.id = t6.id_resp and t6.nivel = 2) 
                 LEFT JOIN tb_teste t7 on (t6.id = t7.id_resp and t7.nivel = 2) 
                 LEFT JOIN tb_teste t8 on (t7.id = t8.id_resp and t8.nivel = 2) 
                 LEFT JOIN tb_teste t9 on (t8.id = t9.id_resp and t9.nivel = 2) 
                 LEFT JOIN tb_teste t10 on (t9.id = t10.id_resp and t10.nivel = 2) 
                 LEFT JOIN tb_teste t11 on (t10.id = t11.id_resp and t11.nivel = 2) 
                 LEFT JOIN tb_teste t12 on (t11.id = t12.id_resp and t12.nivel = 2) 
                 LEFT JOIN tb_teste t13 on (t12.id = t13.id_resp and t13.nivel = 2) 
                 LEFT JOIN tb_teste t14 on (t13.id = t14.id_resp and t14.nivel = 2) 
                 LEFT JOIN tb_teste t15 on (t14.id = t15.id_resp and t15.nivel = 2) 
WHERE t1.id = 53 



porem e se aumentar a quantidade rsrs ai vai dar erro no sistema , e teri que adicionar mais linhas a esta QUERY a cada problema novo.

mesmo assim muito obrigado, se vc tiver mais alguma dica eu vou ficar muito grato.
Responder Citar

04/12/2015

Dyosse

Imagine Tbm uma Situação ASSIM:

53
 +-60
    +-120
        +-152
        +-154
            +-158
        +-156
    +-142
    +-67
       +-65 

Responder Citar

04/12/2015

Marcos P

É mais simples tratar isso do lado da aplicação, recuperando todos os dados e tratando a montagem da árvore registro-a-registro.

Se vc quiser manter isso do lado do banco, pense e um cursor que também faça esse tratamento registro-a-registro.
Responder Citar

04/12/2015

Marcos P

Jociel,

Isso mesmo... um loop para varrer e tratar os registros. Perfeito !

Parabéns, também, pelo cuidado no detalhamento na sua necessidade ( no posto original ).

Pouquíssima gente que inclui posts no fórum, detalha sua necessidade tão bem e menos gente ainda volta por aqui pra dizer como finalizou o assunto.

Bom final de semana...
Responder Citar