Ir para conteúdo

POWERED BY:

Arquivado

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

Maykel-ctba

[Resolvido] Entre categorias "OR, e entre subcategorias "AND&#

Recommended Posts

Fala galera!

 

Estou com um pepinaço! Estou montando um site de um segmento de produtos, e os mesmos são cadastrados com filtros para refinar as pesquisas... Logo criei 4 tabelas...

 

  • Categorias de filtros
  • Filtros
  • Produtos
  • Produto/filtro (contém o id do produto e do filtro, pois podem ter mais de um filtro por produto).

 

Porém, na prática pelo jeito vou ter que fazer outra coisa... ao fazer os primeiros testes, me deparei com a seguinte situação:

 

Tenho uma categoria PRODUTOS, e outra categoria PRAZO DE ENTREGA. Nestas categorias, cadastrei os seguintes filtros:

 

Categoria Produtos:

  • Mochilas
  • Bolsas

 

Categoria Prazo de Entrega:

  • Pronta-entrega
  • Sob-econmenda

 

Se eu faço uma consulta utilizando OR entre os filtros, que teóricamente poderia dar certo, eu entro no impasse. Se eu seleciono que quero ver apenas as mochilas a pronta entrega... ele vai me trazer também as bolsas, porque elas estão tambem com o filtro PRONTA-ENTREGA. Sacaram?

 

SELECT pro.* FROM produto pro, produto_filtro prf WHERE pro.proAtivo = 'S' AND pro.proExcluido = 'N' AND pro.proTipo = 'P' AND prf.proId = pro.proId AND (prf.filId = 1 OR prf.filId = 8) GROUP BY proId

 

Pensei na seguinte solução, porém não sei como traduzir isso em uma consulta.

 

Preciso que, as buscas ENTRE CATEGORIAS sejam "AND" e entre os filtros sejam "OR".

Exemplificando... quero que busque mochilas que tenham pronta entrega, e me tragam apenas as mochilas que tenham pronta-entrega, e não as bolsas que foram marcadas com pronta-entrega!

 

Alguma luz? Por favoooor! :wacko:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sem bacaolhadas , siri frito ou strogonoff de camarao....

 


select * from tabela
where
categoria in ('mochila')
and entrega in ('agora','encomenda')

 

 

ou seja o que esta em in () representa o "or inter-categorico" e o and eh o and normal entre categorias.

 

entao no exemplo acima eu peço mochila com entrega imediata ou sob-encomenda

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi Giesta, beleza?

 

Cara, eu entro no seguinte problema... Entrega não é uma coluna, nem uma tabela, e sim um registro...

Vou mostrar aqui como estão as tabelas para melhorar a visualização:

 

Tabela CATEGORIA:

capturadetela20120503s1.png

 

Tabela FILTRO:

capturadetela20120503s1.png

 

Tabela PRODUTO:

capturadetela20120503s1.png

 

Tabela PRODUTO-FILTRO:

capturadetela20120503s1.png

 

E no site eu estou mostrando assim:

 

capturadetela20120503s1.png

Os produtos estão sendo exibidos no lado direito, e os filtros e suas categorias no menu esquerdo.

Gostaria que entre as categorias, filtrasse com a interseção "OR" e entre os filtros, fosse "E".

 

Exemplificando:

 

Se a pessoa marcar NECESSAIRE e PRONTA-ENTREGA, deve exibir somente a necessaire da imagem. Hoje, estão exibindo além da necessaire, todos os produtos que foram setados como pronta-entrega!

 

Eu preciso muito de uma ajuda nesse quesito, sei a lógica e não sei como traduzir isso em consultas!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sua tabela tem um problema de logica na minha opniao, ser "feminino" é uma caracteristica, ser "pronta-entrega" é outra caracteristica e ser "bolsa" é outra caracteristica, mas quem sou eu pra criticar modelos dos outros.

 



select * from produto where proId in (
select proId from produto-filtro where fillId in
(
select distinct pf.fillId from produto_filtro pf ,
(select f.*  from filtro f, produto_filtro pf where catFiltroId = 1 and pf.fillId = f.fillId)produto ,
(select f.* from from filtro f, produto_filtro pf where catFiltroId = 2 and pf.fillId = f.fillId )entrega ,
(select f.* from from filtro f, produto_filtro pf where catFiltroId = 3 and pf.fillId = f.fillId)colecao ,
(select f.* from from filtro f, produto_filtro pf where catFiltroId = 4 and pf.fillId = f.fillId )utilidade 
where 
pf.fillId = produto.fillId
and pf.fillId = entrega.fillId
and pf.fillId = colecao.fillId
and pf.fillId = utilidade.fillId
)z
where produto.fillNome in ('Mochila','Bolsa')
and entrega.fillNome in ('Pronta-Entrega')
)
)


 

Entao mais uma vez... (Mochila OR Bolsa) AND (Pronta-Entrega)

 

Espero ter ajudado, mais do que isso só com a base na mao para fazer os testes.

 

 

 

 

Agora pode me enviar uma capa de neoprene pra note 15,5"(sony vaio) e uma mochila maneira rs :P

Compartilhar este post


Link para o post
Compartilhar em outros sites

Exatamente, Giesta, porém eu precisava deixar estas características para o cliente cadastrar, pois a gama de produtos era muito extensa para criar uma coluna "FEMININO"para ele preencher SIM/Não por exemplo.

 

Eu tentei usar a consulta que você mandou (alterando o que achei que devia alterar, claro), e deu Syntax Error... só não sei aonde.. nunca fiz estas consultas mirabolantes, sempre usei o básico do básico do MYSQL :upset:

 

Segue um DUMP do MYSQL caso você queira brincar com isso, e a rodada de chopps quando você vier pra Curitiba é garantida (já que o cliente nao fornece esses itens nem pra gente que é terceirizado ^_^ ):

 

-- phpMyAdmin SQL Dump
-- version 3.2.4
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: May 03, 2012 at 08:06 PM
-- Server version: 5.1.44
-- PHP Version: 5.3.1

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Database: `danka`
--

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

--
-- Table structure for table `sistema_categoriafiltro`
--

CREATE TABLE IF NOT EXISTS `sistema_categoriafiltro` (
 `catFiltroId` int(11) NOT NULL AUTO_INCREMENT,
 `catFiltroTipo` enum('V','M','P') COLLATE ucs2_roman_ci NOT NULL,
 `catFiltroNome` varchar(255) COLLATE ucs2_roman_ci NOT NULL,
 `catFiltroDecisao` enum('E','OU') COLLATE ucs2_roman_ci NOT NULL,
 `catFiltroAtivo` enum('S','N') CHARACTER SET utf8 NOT NULL,
 `catFiltroExcluido` enum('S','N') CHARACTER SET utf8 NOT NULL,
 PRIMARY KEY (`catFiltroId`)
) ENGINE=MyISAM  DEFAULT CHARSET=ucs2 COLLATE=ucs2_roman_ci AUTO_INCREMENT=5 ;

--
-- Dumping data for table `sistema_categoriafiltro`
--

INSERT INTO `sistema_categoriafiltro` (`catFiltroId`, `catFiltroTipo`, `catFiltroNome`, `catFiltroDecisao`, `catFiltroAtivo`, `catFiltroExcluido`) VALUES
(1, 'P', 'Produto', 'E', 'S', 'N'),
(2, 'P', 'Prazo de entrega', 'OU', 'S', 'N'),
(3, 'P', 'Coleção', 'OU', 'S', 'N'),
(4, 'P', 'Utilidade', 'E', 'S', 'N');

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

--
-- Table structure for table `sistema_filtro`
--

CREATE TABLE IF NOT EXISTS `sistema_filtro` (
 `filId` int(10) NOT NULL AUTO_INCREMENT,
 `filNome` varchar(255) NOT NULL,
 `catFiltroId` int(10) NOT NULL,
 `filAtivo` enum('S','N') NOT NULL,
 `filExcluido` enum('S','N') NOT NULL,
 PRIMARY KEY (`filId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;

--
-- Dumping data for table `sistema_filtro`
--

INSERT INTO `sistema_filtro` (`filId`, `filNome`, `catFiltroId`, `filAtivo`, `filExcluido`) VALUES
(1, 'Mochila', 1, 'S', 'N'),
(2, 'Necessaire', 1, 'S', 'N'),
(3, 'Capa/Case notebook', 1, 'S', 'N'),
(4, 'Maleta/Bolsa executiva', 1, 'S', 'N'),
(5, 'Sacola', 1, 'S', 'N'),
(6, 'Bolsa térmica', 1, 'S', 'N'),
(7, 'Porta-tênis', 1, 'S', 'N'),
(8, 'Pronta-entrega', 2, 'S', 'N'),
(9, 'Sob encomenda', 2, 'S', 'N'),
(10, 'Info', 3, 'S', 'N'),
(11, 'Sportif', 3, 'S', 'N'),
(12, 'Congresso', 3, 'S', 'N'),
(13, 'Para notebooks', 4, 'S', 'N'),
(14, 'Eventos/congressos', 4, 'S', 'N'),
(15, 'Viagem', 4, 'S', 'N'),
(16, 'Executivo', 4, 'S', 'N'),
(17, 'Academia/esportes', 4, 'S', 'N'),
(18, 'Feminino', 4, 'S', 'N'),
(19, 'Bolsas', 1, 'S', 'N');

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

--
-- Table structure for table `sistema_produto`
--

CREATE TABLE IF NOT EXISTS `sistema_produto` (
 `proId` int(10) NOT NULL AUTO_INCREMENT,
 `proTipo` enum('V','M','P') NOT NULL,
 `proCodigo` varchar(255) NOT NULL,
 `proNome` varchar(255) NOT NULL,
 `proDescricao` text NOT NULL,
 `proMedida` varchar(255) NOT NULL,
 `proMaterial` varchar(255) NOT NULL,
 `proQuantidadeMinima` int(10) NOT NULL,
 `proUrl` varchar(255) NOT NULL,
 `proAtivo` enum('S','N') NOT NULL,
 `proExcluido` enum('S','N') NOT NULL,
 PRIMARY KEY (`proId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--
-- Dumping data for table `sistema_produto`
--

INSERT INTO `sistema_produto` (`proId`, `proTipo`, `proCodigo`, `proNome`, `proDescricao`, `proMedida`, `proMaterial`, `proQuantidadeMinima`, `proUrl`, `proAtivo`, `proExcluido`) VALUES
(1, 'P', '11164', 'Bolsa Sportif Média', '<p>Bolsa esportiva pequena. Em formato meia-lua, com bolsos laterais em tela e abertura principal em "U", ótima para academias.</p>', '<p>42 x 22 16 cm.</p>\r\n<p> </p>', '<p>Poliéster 600 Nacional</p>', 30, '', 'S', 'N'),
(2, 'P', '11163', 'Bolsa Sportif Grande', '<p>Bolsa esportiva grande. Com design diferenciado conta dois ótimos bolsos laterais e um pequeno bolso frontal, além de alça tiracolo.</p>', '<p>66 x 36 x 29 cm.</p>', '<p>Poliéster 600 Nacional</p>', 30, '', 'S', 'N'),
(3, 'P', '7051', '7051', '<p>Mochila,com alça transversal e com fechamento em velcro,contem um bolso frontal com abertura em zíper na vertical com 2 porta canetas e um porta calculadora/celular, e ao lado direito com um bolsinho chapado na parte externa, possui ainda compartimento principal com abertura em zíper.</p>', '<p>29x42x9 cm.</p>', '<ul>\r\n    <li>100% poliéter córdoba impermeável com revestimento em PU;</li>\r\n    <li>100% Poliéster 600 plastificado.</li>\r\n</ul>\r\n<p> </p>', 200, '', 'S', 'N'),
(4, 'P', '11207', 'Necessaire Sportif', '<p>Necessaire simples com 1 compartimento.</p>', '<p>24 x 10 x 14 cm</p>\r\n<p> </p>', '<p>Poliéster 600 Nacional</p>', 30, '', 'S', 'N'),
(5, 'P', '11216', 'Bolsa Messenger Horizontal', '<p>Bolsa tipo carteiro. Possui um compartimento principal. Abertura com fecho tic tac. Possui compartimento para guardar caneta, calculadora.</p>\r\n<p> </p>', '<p>Poliester 600 com detalhes em laminado sintetico.</p>\r\n<p> </p>', '<p>39 x 27 x 11 cm</p>\r\n<p> </p>', 30, '', 'S', 'N');

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

--
-- Table structure for table `sistema_produto_filtro`
--

CREATE TABLE IF NOT EXISTS `sistema_produto_filtro` (
 `proId` int(10) NOT NULL,
 `filId` int(10) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `sistema_produto_filtro`
--

INSERT INTO `sistema_produto_filtro` (`proId`, `filId`) VALUES
(1, 11),
(1, 8),
(1, 19),
(5, 16),
(2, 17),
(2, 11),
(2, 19),
(4, 18),
(3, 14),
(3, 13),
(3, 9),
(3, 1),
(3, 16),
(4, 17),
(4, 15),
(4, 14),
(4, 11),
(4, 8),
(4, 2),
(1, 17),
(5, 14),
(5, 12),
(5, 9),
(5, 8),
(5, 19);

 

 

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

 

 

Consulta utilizada:

select * from sistema_produto where proId in (

select proId from sistema_produto_filtro where fillId in

(

select distinct pf.fillId from produto_filtro pf ,

(select f.* from sistema_filtro f, sistema_produto_filtro pf where catFiltroId = 1 and pf.fillId = f.fillId) produto ,

(select f.* from from sistema_filtro f, sistema_produto_filtro pf where catFiltroId = 2 and pf.fillId = f.fillId ) entrega ,

(select f.* from from sistema_filtro f, sistema_produto_filtro pf where catFiltroId = 3 and pf.fillId = f.fillId) colecao ,

(select f.* from from sistema_filtro f, sistema_produto_filtro pf where catFiltroId = 4 and pf.fillId = f.fillId ) utilidade

where

pf.fillId = produto.fillId

and pf.fillId = entrega.fillId

and pf.fillId = colecao.fillId

and pf.fillId = utilidade.fillId

)

where produto.fillNome in ('Mochila','Bolsa')

and entrega.fillNome in ('Pronta-Entrega')

)

)

 

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 'from sistema_filtro f, sistema_produto_filtro pf where catFiltroId = 2 and pf.fi' at line 6

Compartilhar este post


Link para o post
Compartilhar em outros sites

com os dados fica facil.

 

 


select * from sistema_produto where proId in
(
SELECT spf.proId  FROM sistema_produto_filtro spf, sistema_filtro sf where spf.filId = sf.filId group by spf.proId
having 
(group_concat('X',sf.catFiltroId,'-',sf.filId,'X') like '%X1-1X%' or group_concat('X',sf.catFiltroId,'-',sf.filId,'X') like '%X1-2X%')
and ( group_concat('X',sf.catFiltroId,'-',sf.filId,'X') like '%X2-8X%')
)

 

 

 

na primeira linha do having você preenche com os dados do grupo 1 por exemplo X1-1X, X1-2X

na segunda linha do having você preenche com o segundo grupo, exemplo X2-8X

e assim por diante.

 

 

acessei o site da loja, os produtos sao interessantes,pena q nao tem preço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Giesta, incrivel! AHAHAHAH! :thumbsup:

Funcionou perfeitamente...

 

agora vou tentar aplicar lá no meu sistema...

 

O novo site vai ser bem melhor do que o que está lá, com orçamentos online e tudo mais...

 

Só uma dúvida... para cada ID de filtro que o cara escolher, eu adiciono mais um GROUP CONCAT?

Compartilhar este post


Link para o post
Compartilhar em outros sites

isso ai, ai você cria seus AND e OR conforme a necessidade da sua logica dentro do HAVING

 

essa solução não é otima, talvez se você tivesse uma view ou uma tabela com o group_concat pronto seria melhor, com o tamanho do sistema essa soluçao pode começar a lerdar, mas do jeito q eu fiz você esta preparado para qualquer evolução em termos de aumento de categoria e sub categoria.

 

Ah agora ja pode mandar a malinha pra lap de 15.5'' e uma mochila maneira :P

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi! Vou tentar a tarde encaixar isso no PHP para ver como posso fazer!

 

Cara, se eles nao vendessem apenas em quantidade, pode crer que eu te mandava uma mochilinha, pena que eles vendem apenas de 30 pra cima :unsure:

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.