Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido)Select único, através de dados em três tabelas


vini_loock

Pergunta

Olá pessoal, hoje vou precisar de uma ajudinha ai de quem é fera com SQL.

Tenho três tabelas:

  1. positions, responsável por guardar as posições em que um módulo será carregado
  2. modules, guarda todos os módulos que existem na aplicação
  3. pages_modules, aqui, quando o módulo puder ser exibido em apenas algumas páginas, fica guardado o id da página e o id do módulo. Um registro para cada página, independente de o modulo ser atribuído em 1 ou 30 páginas.
Vou postar aqui o SQL das tabelas acima para facilitar um pouco:
CREATE TABLE IF NOT EXISTS `modules` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `alias` varchar(255) NOT NULL,
  `module` varchar(255) NOT NULL,
  `state` int(11) NOT NULL,
  `params` text NOT NULL,
  `pages` int(11) NOT NULL,
  `position` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `modules` (`id`, `title`, `alias`, `module`, `state`, `params`, `pages`, `position`) VALUES
(1, 'Header', 'header', 'mod_header', 1, '', 2, 1);


CREATE TABLE IF NOT EXISTS `pages_modules` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `itemid` int(11) NOT NULL,
  `moduleid` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `pages_modules` (`id`, `itemid`, `moduleid`) VALUES
(1, 1, 1);


CREATE TABLE IF NOT EXISTS `positions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
INSERT INTO `positions` (`id`, `name`) VALUES
(1, 'header');
No PHP, tenho uma função que passa o "name"(tabela positions) de uma posição; Essa função, faz um select como abaixo:
SELECT * FROM positions WHERE name = 'nome_passado_como_parametro' LIMIT 1
Depois dessa query, pego o id da position retornada e faço um SELECT na tabela "modules" em todos os registros em que: position seja igual ao id da posição retornada na query anterior; state for igual a 1, que no meu código, representa publicado.
SELECT * FROM modules WHERE state = 1 AND position = 'id_da_position'
Logo após, faço um "foreach" e dentro deste, faço uma nnova query. Dessa vez, na tabela "pages_modules", verifico se existe algum registro, cujo "positionid" seja igual ao id retornado na primeira query e "moduleid" for igual ao id do item atual no foreach.
SELECT * FROM pages_modules WHERE positionid = 'id_da_posição' AND moduleid = 'id_do_modulo'
Como podem ver, isso fica uma bagunça no código, nada bonito, nada semantico e deixa o processo lento. O que eu quero fazer, é "juntar" essas 3 queries em uma só, porem, não faço nem ideia de como fazer isso. Se alguém puder ao menos me dar o caminho das pedras, agradeço muito. Caso em alguma parte eu não tenha sido claro o bastante, não hesite em avisar para que eu possa tentar melhorar. Abç, Vinicius Talvez possa ajudar o fonte da função:
</php
        private function modules_get_num($position){
            global $db;
            $num = 0;
            $itemid = Request::getVar('itemid', 1, 'get', 'int');
        
            /*
                seleciona a posição e salva o id em $position_id
            */
            $query = "SELECT * FROM positions WHERE name = '$position'";
            $db->seQuery($query);
            $db->query();
            $position = $db->loadObject();
            $position_id = (int) $position->id;
            
            
            /*
                seleciona os modulos publicados com a posição passada como parametro
            */
            $query = "SELECT * FROM modules WHERE state = 1 AND position = $position_id";
            $db->setQuery($query);
            $db->query();
            $modules = $db->loadObjectList();
            foreach($modules as $module){
                if($module->pages == 1){
                    //todas as páginas
                    $num++;
                }else if($module->pages == 2){
                    //algumas páginas
                    $query = "SELECT * FROM pages_modules WHERE itemid = $itemid AND moduleid = $module->id";
                    $db->setQuery($query);
                    $db->query();
                    $num += $db->getNumRows();
                }
            }
            return $num;
        }
?>
Edit... Então.. por motivos do alem, fui ver o perfil de um usuário aqui no forum e no ultimo tópico dele estafa falando sobre um tal de JOIN, então dei uma olhada na doc do mysql e vi que era aquilo que precisava. A query ficou assim:
SELECT m.module
FROM modules m
JOIN positions p ON p.name = '$position' AND p.id = m.position
JOIN pages_modules pm ON m.pages = 1 OR m.pages = 2 AND pm.itemid = $itemid AND moduleid = m.id

Só uma obs: seria interessante mover o tópico para mysql, pois só agora percebi que postei nessa área.

Bom, é isso pessoal, até a próxima!

Editado por vini_loock
Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...