Jump to content
gust.php

Produtos, categorias e subcategorias.

Recommended Posts

Prezados, boa noite.

 

Nunca fiz isso e estou dúvidas.

 

Tenho as tabelas CATEGORIAS e SUBCATEGORIAS. Os cadastros e relacionamentos estão funcionando perfeitamente, tudo ok aqui.

Tenho também a tabela PRODUTOS.

 

Digamos que eu tenha produtos que fazem parte de categorias que não tem subcategoria, e tenho produtos que fazem parte de subcategorias de alguma categoria.

 

Como fazer o relacionamento desses produtos?

 

Vou relacionar a tabela PRODUTOS com CATEGORIAS e SUBCATEGORIAS ?

A dúvida surgiu pois um produto pode fazer parte de uma categoria que não tem subcategoria, mas posso ter também produtos que fazem parte de subcategorias de uma categoria.

E qual a cardinalidade desse relacionamento?

 

Ja vi gente fazendo o relacionamento só com SUBCATEGORIA, mas e se não existir subcategoria????

 

produto many to many categoria

produto many to many subcategoria

 

produto

id | produto 

 

prod_cat

cat_id | prod_id

 

categoria

id | categoria 

 

subcategoria

id | categoria 

 

prod_subcat

subcat_id | prod_id

 

Como resolver isso de um forma correta?

Share this post


Link to post
Share on other sites

Vamos lá!

 

Primeiramente, fiz um exemplo meio

que chatinho, a query é bem grande,

porém não deixa de ser funcional...

 

Sem mais de longas, vamos a ela!

 

 

TABELAS+DADOS A SER UTILIZADAS(OS)

CREATE DATABASE db_01;
USE db_01;

CREATE TABLE categoria (
	id INT NOT NULL AUTO_INCREMENT,
	categoria VARCHAR(60) NOT NULL,
	PRIMARY KEY(id)
);
INSERT INTO categoria (categoria) VALUES
('Televisor'),
('Notebook'),
('Adaptador');

CREATE TABLE produto (
	id INT NOT NULL AUTO_INCREMENT,
	produto VARCHAR(60) NOT NULL,
	PRIMARY KEY(id)
);
INSERT INTO produto (produto) VALUES
('Televisor Samsung'),
('Notebook Samsung'),
('Televisor LG'),
('Adaptador HMDI'),
('Televisor Gnusmas'),
('Notebook Acer'),
('Adaptador Universal');

CREATE TABLE prod_cat (
	id INT NOT NULL AUTO_INCREMENT,
	cat_id INT NOT NULL,
	prod_id INT NOT NULL,
	PRIMARY KEY (id),
	FOREIGN KEY (cat_id) REFERENCES categoria (id),
	FOREIGN KEY (prod_id) REFERENCES produto (id)
);
INSERT INTO prod_cat (cat_id, prod_id) VALUES
(3, 4),
(3, 7);

CREATE TABLE subcategoria (
	id INT NOT NULL AUTO_INCREMENT,
	cat_id INT NOT NULL,
	categoria VARCHAR(60) NOT NULL,
	PRIMARY KEY(id),
	FOREIGN KEY (cat_id) REFERENCES categoria (id)
);
INSERT INTO subcategoria (cat_id, categoria) VALUES
(1, 'LG'),
(2, 'Samsung'),
(1, 'Samsung'),
(1, 'Gnusmas'),
(2, 'Acer');

CREATE TABLE prod_subcat (
	id INT NOT NULL AUTO_INCREMENT,
	subcat_id INT NOT NULL,
	prod_id INT NOT NULL,
	PRIMARY KEY(id),
	FOREIGN KEY (subcat_id) REFERENCES subcategoria (id)
);
INSERT INTO prod_subcat (subcat_id, prod_id) VALUE
(1, 3),
(3, 1),
(2, 2),
(4, 5),
(5, 6);

 

RELACIONAMENTO DAS TABELAS

image.png.5f12f26646a9caa0a4e54c1d984eeec3.png

 

QUERY

SELECT
	p.id AS 'idProduto',
	cp.cat_id AS 'idCategoria',
	ps.subcat_id AS 'idSubCategoria',
	p.produto AS 'nomeProduto',
	c.categoria AS 'nomeCategoria',
	sc.categoria AS 'nomeSubCategoria'
FROM
	produto p
LEFT JOIN
	prod_cat cp
ON
	( p.id = cp.prod_id )
LEFT JOIN
	prod_subcat ps
ON
	( p.id = ps.prod_id )
LEFT JOIN
	subcategoria sc
ON
	( ps.subcat_id = sc.id )
LEFT JOIN
	categoria c
ON
	c.id = CASE
		WHEN
			cp.cat_id IS NULL
		THEN
			sc.cat_id
		ELSE
			cp.cat_id
	END
ORDER BY
	p.id
;

 

RESULTADO

image.png.f360481e530ba4ec361ef28b9f13900b.png

 

EXPLICAÇÃO

Basicamente o'que fizemos foi obter

todos os produtos, onde "verificamos"

através do LEFT JOIN se o mesmo

está ou não nas tabelas onde contém

os relacionamentos...

 

Caso não exista em uma tabela, então

atravéz do LEFT JOIN o mesmo será

dado como NULL...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By gersonab
      Bom dia, tenho 2 tabelas editáveis em uma div, estas funcionam normalmente, o problema é que o loop não acontece , só carrega sobre 1 item, sendo que este eu posso ter mais itens.
       na página principal tenho:
      <div class="carregadados"></div> function fetch_data() { $.ajax({ url:"../lista/finan.php", method:"POST", success:function(data){ $('.carregadados').html(data); } }); } fetch_data(); a página a ser carregada esta assim:
      <?php session_start(); require_once('config.php'); $output = ''; $idc1=$_SESSION['idc']; $sql01 = "SELECT * FROM porcent WHERE idfcli='$idc1'"; $result = mysqli_query($con, $sql01); while($user41 = mysqli_fetch_array($result)){ // primeiro while onde seleciono os itens da pessoa podendo ter vários $output .= ' <div class="table-responsive mb-4 mt-4"> Aqui vem os dados da pessoa '; $id1= $user41["idproc"]; $sqladv = "SELECT * FROM poradv WHERE procav='$id1'"; $resulta = mysqli_query($con, $sqladv); $output .= ' <table class="table table-bordered table-hover table-striped" style="width:100%"> <thead> <tr> </tr> </thead> <tbody>'; if(mysqli_num_rows($resulta) > 0) { while($usera = mysqli_fetch_array($resulta)){ //segundo while onde tenho os dados de venda em uma tabela editavel $output .= ' <tr> </tr>'; } $output .= ' <tr> // insiro linhas caso precise </tr> '; } else { $output .= '<tr> // caso não tenha nada inserido, posso fazer por aqui </tr> '; } $output .= '</tbody> </table>'; $id2= $user41["idproc"]; $sql = "SELECT * FROM parcelas WHERE procid='$id2' ORDER BY datapar, idpar ASC"; $result = mysqli_query($con, $sql); $output .= ' <table class="table table-bordered table-hover table-striped" style="width:100%"> <thead> <tr> // tabela de pagamentos editavel </tr> </thead> <tbody>'; if(mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_array($result)) { //terceiro while , tabela referente a pagamentos $output .= ' <tr> // tabela pagamentos </tr>'; } $output .= ' <tr> // insiro linhas caso precise </tr> '; } else { $output .= '<tr> // caso não tenha nada inserido, posso fazer por aqui </tr> '; } $output .= '</tbody> </table> </div> '; } echo $output; ?> só esta carregando uma vez , tudo dentro da parte editável esta funcionando, porém no primeiro while só faz 1 loop, os demais estão funcionando perfeitamente.
      desde já agradeço qualquer ajuda.
    • By gersonab
      Boa tarde a todos, tenho um sistema de upload de arquivos que funciona perfeitamente, agora eu gostaria que estes arquivos fossem armazenados em nuvem, não no servidor, poderiam indicar um tutorial ou como proceder.
    • By k9studio
      Olá Pessoal,
       
      Tenho um campo em uma tabela que grava os dados neste formato a baixo:
      {""user_id":"1","user_token":"5181e24c8a7e60304156e08595f48ad6"}
       
      como faço para chamar esses dados no php separados...
       
      fico grato se alguém puder ajudar..
    • By adrianno
      Boa noite, tenho a seguinte questão, tenho uma tabela com  campo  "valor"  que guarda um valor monetário e campo "data" com a data do lançamento e um campo "tipo" marcando se é entrada ou saida,  ao cadastrar um valor, coloco a data e qual tipo "entrada" ou "saida"    quero montar uma view que soma todos os valores por mês, separados por tipo, se é entrada ou saida.   A seguinte query me tras a soma, porém não agrupa pelo MES/ANO
      SELECT DATE_FORMAT(data, "%m/%Y") as MES, (select Sum(valor) from controle WHERE tipo = 'SAIDA' ) as VS, // soma tudo que for SAIDA (select Sum(valor) from controle WHERE tipo = 'ENTRADA' ) as VE // soma tudo que for ENTRADA FROM controle GROUP BY YEAR(data), MONTH(data) // agrupa por ANO/MES mas este grupo nao opera nas somas dos valores ORDER BY data DESC  Esta query  somas os valores  mas não filtra pelo mes/ano e tras a soma total de tudo ignorando o mes,  mostra o mesmo valor total de cada tipo em todos os meses:
      EXEMPLO DO RESULTADO
      MES                 VS(saida)     VE(entrada)
      06/2020         4600,00        9750,00
      05/2020         4600,00        9750,00
      04/2020         4600,00        9750,00
       
      Na prática cada mês deveria retornar as somas dos valores apenas dele. Como fazer com que  GROUP BY YEAR(data), MONTH(data)   tenha efeito correto em cada tipo?   
    • By Rebeca Julia Bronzatti
      Oiê gente, eu queria a ajuda de vocês numa coisa que acredito ser simples, mas como sou iniciante tô encontrando dificuldade, é eu tenho duas tabelas uma chamada imóvel e outra arquivoimagem, onde em imóvel eu tenho os dados de um imóvel e em arquivoimagem o nome das imagens e os id delas, eu tô com um problema tanto no SGC quanto no site final, por se tratar de uma imobiliária os imóveis terão mais de uma imagem associadas a ele o dilema é que na hora que eu trago esses dados ele fica me replicando, por exemplo eu tenho um imóvel com 5 imagens associadas a ele, ele réplica esses dados 5 vezes, mudando somente a imagem, só que isso é inútil pra mim. Eu tenho ciência que o código da forma que está faz exatamente o que falei, problema é que eu não sei como mudar isso para o real objetivo.  
      Eu queria que ele viesse somente uma imagem da base de dados associada aquele imóvel, se alguém puder me ajudar eu agradeço.
      $result_imoveis = "SELECT imovel.id, imovel.tipo, imovel.locacao, imovel.valorLocacao, imovel.numQuartos, imovel.numSuites, imovel.numBanheiros, imovel.status, imovel.numVagas, imovel.descricao, imovel.rua, imovel.num, imovel.bairro, arquivoimagem.arquivo FROM imovel INNER JOIN arquivoimagem ON imovel.id = arquivoimagem.imovel_id WHERE locacao = 'Sim' AND status = 'Disponível'"; $resultado_imoveis = mysqli_query($cnn, $result_imoveis); $total_imoveis = mysqli_num_rows($resultado_imoveis); //Seta a quantidade de cursos por pagina $quantidade_pagina = 8; //Calcular o número de página necessaria $num_paginas = ceil($total_imoveis / $quantidade_pagina); //Calcula o inicio da visuzalização $inicio = ($quantidade_pagina * $pagina) - $quantidade_pagina; //Selecionar os imoveis a serem apresentados na página $consultaPagina = "SELECT imovel.id, imovel.tipo, imovel.locacao, imovel.valorLocacao, imovel.numQuartos, imovel.numSuites, imovel.numBanheiros, imovel.status, imovel.numVagas, imovel.descricao, imovel.rua, imovel.num, imovel.bairro, arquivoimagem.arquivo FROM imovel INNER JOIN arquivoimagem ON imovel.id = arquivoimagem.imovel_id WHERE locacao = 'Sim' AND status = 'Disponível' LIMIT $inicio, $quantidade_pagina"; $conPagina = mysqli_query($cnn, $consultaPagina); $total_imoveis = mysqli_num_rows($conPagina); <?php while ($dado = $conPagina->fetch_array()) { $dado['id']; ?> <div class="col s12 m12 l6"> <div class="card"> <div class="card-image"> <img src="<?php echo 'http://localhost/SGC/arquivo/' . $dado ['arquivo']; ?>" class="img-responsive"> <span class="card-title"><?php echo $dado['tipo']; ?></span> </div> <div class="card-content"> <p><?php echo $dado['descricao']; ?></p> <br> <div class="detalhes center-align"> <div class="number "><img src="img/cama.png" style="margin-left: 10px; margin-right: 8px;"><?php echo $dado['numQuartos']; ?></div><br> <div class="number "><img src="img/garagem.png" style="margin-left: 10px; margin-right: 8px;"><?php echo $dado['numVagas']; ?></div><br> <div class="number "><img src="img/banheiro.png" style="margin-left: 10px; margin-right: 8px;"><?php echo $dado['numBanheiros']; ?></div> <div class="number "><img src="img/suite.png" style="margin-left: 10px; margin-right: 8px;"><?php echo $dado['numSuites']; ?></div> </div> </div> <div class="card-action"> <a href="<?php echo "imovel.php?id=" . $dado['id'] ?>"><button type="submit" name="action" class="btn waves-effect waves-ligth btn-small right"> Ver Mais</button></a> <a class="valor" href="#">R$ <?php echo number_format($dado["valorLocacao"], 2, ',', '.');?></a> </div> </div> </div> <?php } ?>  
×

Important Information

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