Jump to content
Fórum Script Brasil
  • 0

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


vini_loock

Question

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!

Edited by vini_loock
Link to comment
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152.2k
    • Total Posts
      652k
×
×
  • Create New...