Jump to content

Archived

This topic is now archived and is closed to further replies.

Maykel-ctba

Busca em várias categorias

Recommended Posts

Fala galera,

Tenho a seguinte questão: tenho um site com vários produtos, e cada produto pode ter mais de uma categoria.

O Cadastro está OK, mas agora o cliente me solicitou uma espécie de busca avançada:

Segue um modelo e seus respectivos IDs (formato: id grupo-id categoria):

 

POR PRODUTO

Mochilas (1-1)
Pastas & Maletas (1-2)
Cases Tablet & Notebook (1-3)
Necessaires (1-4)
Termomoldados (1-5)
Promoções (1-6)
POR AÇÃO
Para Feiras e Congressos (2-7)
Para Brinde em Ação Promo (2-8)
Para Brinde a Colaboradores (2-9)

Gostaria que se a pessoa selecionasse Mochilas e Pastas, fosse uma consulta OR, e entre os grupos (Produto e ação), uma consulta AND.
Tentei da seguinte maneira (minha função PHP já faz a separação automaticamente de categorias e grupos para montar a consulta):
SELECT p.*

FROM sistema_produto p, sistema_produto_secao ps

WHERE proAtivo = 'S'
AND proExcluido = 'N'
AND p.proId = ps.proId
AND /* Grupo 01 */ (ps.secId = 1 OR ps.secId = 2)
AND /* Grupo 02 */ (ps.secId = 7)
GROUP BY p.proId

Se eu só seleciono categorias em um grupo, funciona legal. Mas quando adiciono mais um grupo a busca (no caso do exemplo, a busca pelo ID 7), ele não retorna. Já conferi, e o produto está cadastrado corretamente: o mesmo produto está nas 3 categorias através da tabela intermediária sistema_produto_secao.

 

Suponho que não funcione pois só existe um campo secId, obviamente, e ele só tem um valor.

 

Mas, não me vem a cabeça como posso fazer.

 

Alguma luz?

 

Share this post


Link to post
Share on other sites

Não entendi bem o que você pretente, mas se cada produto pode ter mais de uma categoria, não seria o caso de você criar uma categoria chamada feira, promo, brindes e etc., e depois fazer a busca por estas categorias para exibir os produtos?

Share this post


Link to post
Share on other sites

Leo, já é feito isso. As categorias são criadas. Mas ele pode escolher varias categorias ao mesmo tempo, entendeu? Porém, não é só fazer uma condição OU entre elas.

 

Existem Grupos de categorias.

 

Grupo 01

- Categoria 01

- Categoria 02

- Categoria 03

 

Grupo 02

- Categoria 04

- Categoria 15

 

Eu posso escolher ver produtos da categoria 01 ou 02 que façam parte da categoria 15.

Share this post


Link to post
Share on other sites

@Motta Cara, pensei no IN, mas acho que não me servirá, já que o mesmo trará produtos em todas estas categorias. Mas minha necessidade precisa de uma espécie de "condicional".

 

Vou explicar visualmente.

 

Tabela sistema_produto

 

BgKCPWR.png

 

Tabela sistema_secao

 

3cJ972z.png

 

Tabela sistema_produto_secao

 

yp6HrFx.png

 

Para exemplificar melhor o que preciso:

 

Preciso trazer os produtos que constam em (Mochilas OU Pastas) E (Para feiras e congressos)

 

rfSIos5.png

Share this post


Link to post
Share on other sites

Como em sistema_produto_secao se sabe se é produtto ou secao ?!

 

Por exemplo produto 1 tem 5,6,e 15 mas de que ?

Share this post


Link to post
Share on other sites

proId = produto

secId = secao

 

Os itens que estão nessa imagem laranja são todas seções.

 

Exemplo: Produto 01 é Mochila (Secao 1) e também faz parte da seção Para Feiras e blabla (Seção 13). Produto 02 é um Case (Seção 3) e também serve para feiras (seção 13).

 

Para trazer ambos resultados, a consulta deverá ser:

 

// * Mochilas ou cases Que estão em Feiras e blabla

secId = ((1 OR 3) AND (13))

Share this post


Link to post
Share on other sites

Não se tem um campo em sistema_produto_secao que indique que é produto ou seção !?

 

Fica confuso isto !

 

Como diferenciar um "4" de um com o de outro !?

Share this post


Link to post
Share on other sites

Cara, o próprio campo diferencia. A tabela serve para sabermos quais produtos fazem parte de quais seções.

 

Produto 01 faz parte de seção 02, 03, etc...

Produto 02 faz parte de sécão 01, 03, etc...

 

Table sistema_produto_secao

  • pseId (FK)
  • secId (ID seção)
  • proId (ID produto)

Preenchido fica mais fácil entender.

 

Exemplo:

 

pseId - secId - proId

1 3 1

 

Isso indica que o produto de ID 01 pertence a seção de ID 03.

 

Entendeu? hehehe

Share this post


Link to post
Share on other sites

Então seria algo do tipo

select *
from sistema_produto_secao
where ( (secId  in (1,2) 
         or
        (proId in (13,14)) )

trocando o OR por um AND caso deve atender as duas condições

Share this post


Link to post
Share on other sites

@Motta, primeiramente muito obrigado pela sua paciência com meu caso! Estou aprendendo muito!

 

Cara, fiz o teste e não retornou o resultado esperado. Tanto com OR quanto com AND.

 

Corrigi também um erro de syntax que tinha na sua consulta-exemplo.

SELECT *
FROM sistema_produto_secao
WHERE  (
   (secId IN (1,2))
        AND
   (proId IN (13,14))
)

Com OR, retornou 5 produtos.

Com AND, retornou 0.

 

Porém, pela minha lógica, deveria retornar apenas um produto:

 

Seção 01 OU 02

Contém os produtos 1, 2, 4, 5, 7

E

Seção 13 OU 14

contém o produto 4, 6, 7

Neste caso, não deveria trazer apenas o produto 4 e 7?

Share this post


Link to post
Share on other sites

Os tipos de campo? INT(10).

 

Quer dar uma olhada no dump?

CREATE TABLE IF NOT EXISTS `sistema_produto` (
  `proId` int(10) NOT NULL AUTO_INCREMENT,
  `proTitulo` varchar(255) NOT NULL,
  PRIMARY KEY (`proId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

INSERT INTO `sistema_produto` (`proId`, `proTitulo`) VALUES
(1, 'Mochila Prius'),
(2, 'Soft case '),
(3, 'Necessaire termomoldada'),
(4, 'Maleta Neo Ultraslim'),
(5, 'Mochila Danka Neo Traveller'),
(6, 'Necessaire Sportif Top'),
(7, 'Saco mochila básico'),
(8, 'Necessaire Trading');




CREATE TABLE IF NOT EXISTS `sistema_produto_secao` (
  `prsId` int(10) NOT NULL AUTO_INCREMENT,
  `proId` int(10) NOT NULL,
  `secId` int(10) NOT NULL,
  PRIMARY KEY (`prsId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=206 ;

INSERT INTO `sistema_produto_secao` (`prsId`, `proId`, `secId`) VALUES
(140, 1, 5),
(139, 1, 6),
(138, 1, 15),
(178, 2, 5),
(177, 2, 6),
(176, 2, 2),
(148, 3, 5),
(147, 3, 6),
(186, 4, 5),
(185, 4, 6),
(184, 4, 2),
(183, 4, 19),
(182, 4, 13),
(161, 5, 5),
(160, 5, 6),
(159, 5, 15),
(158, 5, 1),
(175, 2, 17),
(194, 6, 5),
(193, 6, 6),
(181, 4, 15),
(192, 6, 14),
(180, 4, 3),
(179, 4, 11),
(137, 1, 1),
(174, 2, 3),
(146, 3, 4),
(157, 5, 11),
(191, 6, 4),
(197, 7, 6),
(196, 7, 14),
(195, 7, 1),
(205, 8, 4),
(204, 8, 11);




CREATE TABLE IF NOT EXISTS `sistema_secao` (
  `secId` int(10) NOT NULL AUTO_INCREMENT,
  `secTitulo` varchar(255) NOT NULL,
  PRIMARY KEY (`secId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;

INSERT INTO `sistema_secao` (`secId`, `secTitulo`) VALUES
(1, 'Mochilas'),
(2, 'Pastas & Maletas'),
(3, 'Cases Tablet & Notebook'),
(4, 'Necessaires'),
(5, 'Termomoldados'),
(6, 'Promoções'),
(11, 'Acabamento termomoldado'),
(12, 'Acabamento costurado'),
(13, 'Para Feiras e Congressos'),
(14, 'Para Brinde em Ação Promo'),
(15, 'Para Brinde a Colaboradores');

Share this post


Link to post
Share on other sites

O que acontece é que no seu modelo os registros devem estar no mesmo registro * , eu mudaria este modelo , até daria para resolver por uma sql mas um modelo ruim tende a complicar as coisas.

 

 

faria algo do tipo :

categoria
-------------
cod_categoria
tipo_categoria (produto ,secao)
nome_categoria


produto_categoria
-------------------------
cod_produto
cod_categoria

Share this post


Link to post
Share on other sites

Bom, na verdade eu até já tenho isso, só removi do Dump (assim como vários outros campos). Mas não muda em nada. Tenho um campo chamado secTipo, onde todos são = P (Produto).

 

Mas no que isso pode ajudar?

Share this post


Link to post
Share on other sites

Tenta assim Maykel

SELECT proTitulo FROM 
(SELECT prsId, secId, proTitulo, sistema_produto_secao.proId FROM sistema_produto_secao
LEFT JOIN sistema_produto ON sistema_produto.proId = sistema_produto_secao.proId) sub
WHERE proId = 1 AND secId = 5
OR proId = 4 AND secId = 19

Espero que dê certo. :)

Share this post


Link to post
Share on other sites

Com dois campos diferentes a comparação registro a registro exige que ambos atendam a pesquisa.

 

Uma pesquisa do tipo

select *
from produtos
where cod_produto in (select cod_produto
                      from produto_categoria 
                      where categoria in (1,2,4,6,8,12,13))

Share this post


Link to post
Share on other sites

Tá confuso... rs

 

Mas tenta isso daí... A lógica é a mesma:

SELECT DISTINCT grupo1.g1pro AS id, grupo1.g1titulo AS produto FROM (

  (SELECT prsId AS g1prs, secId AS g1sec, proTitulo AS g1titulo, sistema_produto_secao.proId  AS g1pro FROM sistema_produto_secao
  LEFT JOIN sistema_produto ON sistema_produto.proId = sistema_produto_secao.proId)grupo1, 

  (SELECT prsId AS g2prs, secId AS g2sec, proTitulo AS g2titulo, sistema_produto_secao.proId  AS g2pro FROM sistema_produto_secao
  LEFT JOIN sistema_produto ON sistema_produto.proId = sistema_produto_secao.proId)grupo2

)

WHERE g1sec = 5 AND g2sec = 15
AND grupo1.g1pro = grupo2.g2pro

Share this post


Link to post
Share on other sites

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.