Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General »

[RESUELTO] Productos en Multiples Categorias

Estas en el tema de [RESUELTO] Productos en Multiples Categorias en el foro de Bases de Datos General en Foros del Web. Hola a todos, A ver si me consigo explicar, tengo 2 tablas, 1 para productos y otra para categorias. Aparte he echo otra para hacer ...
  #1 (permalink)  
Antiguo 03/02/2009, 13:45
Avatar de b0zZy  
Fecha de Ingreso: enero-2009
Ubicación: Francia
Mensajes: 28
Antigüedad: 15 años, 10 meses
Puntos: 0
Pregunta [RESUELTO] Productos en Multiples Categorias

Hola a todos,
A ver si me consigo explicar, tengo 2 tablas, 1 para productos y otra para categorias. Aparte he echo otra para hacer la relacion "many-to-many". Todas tienen su respectiva PK pero no se como ponerlo en pratica.
Se que tengo que hacer algo asin,
Código PHP:
SELECT tbl_product.pd_idtbl_product.cat_id2tbl_product.cat_id3tbl_category.cat_id
CASE 
WHEN many.cat_id IS NULL 
THEN 
'F'
ELSE 'T'
END AS selected
FROM tbl_product
CROSS JOIN tbl_category
LEFT JOIN many ON 
many.pd_id tbl_product.pd_id
AND many.cat_id tbl_category.cat_id 
WHERE (
tbl_product.cat_id tbl_category.cat_id

pero no me sale como kiero. Me salen todos los productos en todas las categorias.
Y lo que quiero es que cuando elija 1 categoria me salgan todo lo relacionado a la misma.
Gracias

Última edición por b0zZy; 04/02/2009 a las 12:42 Razón: RESUELTO
  #2 (permalink)  
Antiguo 04/02/2009, 01:54
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 8 meses
Puntos: 574
Respuesta: Productos en Multiples Categorias

A ver si te he entendido tienes:

tbl_product
pd_id
pd_nombre
....

tbl_category
cat_id
cat_description
...

many
pd_id
cat_id

y quires poder consultar los productos de una categoria, digamos cat_X?



Código:
Select p.pd_id, p.pd_nombre
     from tbl_product p
where p.pd_id in (Select m.pd_id
           from many m
           where m.cat_id=cat_X)
Es lo que querias?


Quim
  #3 (permalink)  
Antiguo 04/02/2009, 02:54
Avatar de b0zZy  
Fecha de Ingreso: enero-2009
Ubicación: Francia
Mensajes: 28
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Productos en Multiples Categorias

Hola quimfv,
Mira tengo 3 tablas,

tbl_product
pd_id
cat_id
cat_id2
cat_id3
....

tbl_category
cat_id
cat_name
...

many
pd_id
cat_id
cat_id2
cat_id3
...

Y esta query me funciona en sql,

Código PHP:
$sql 'SELECT tbl_product.pd_id, tbl_product.cat_id2, tbl_product.cat_id3, tbl_category.cat_id, 
CASE WHEN many.cat_id IS NULL 
THEN '
F'
ELSE '
T'
END AS selected
FROM tbl_category
CROSS JOIN tbl_product
LEFT JOIN many ON ( many.cat_id = tbl_product.cat_id
AND many.cat_id = tbl_product.cat_id ) 
WHERE (
tbl_product.cat_id = tbl_category.cat_id
)
ORDER BY `tbl_category`.`cat_id` ASC[...]'

Pero en mi category-functions.php,
Código PHP:
<?php
require_once 'config.php';

/*********************************************************
*                 CATEGORY FUNCTIONS 
*********************************************************/

/*
    Return the current category list which only shows
    the currently selected category and it's children.
    This function is made so it can also handle deep 
    category levels ( more than two levels )
*/
function formatCategories($categories$parentId)
{
    
// $navCat stores all children categories
    // of $parentId
    
$navCat = array();
    
    
// expand only the categories with the same parent id
    // all other remain compact
    
$ids = array();
    foreach (
$categories as $category) {
        if (
$category['cat_parent_id'] == $parentId) {
            
$navCat[] = $category;
        }
        
        
// save the ids for later use
        
$ids[$category['cat_id']] = $category;
    }    

    
$tempParentId $parentId;
    
    
// keep looping until we found the 
    // category where the parent id is 0
    
while ($tempParentId != 0) {
        
$parent    = array($ids[$tempParentId]);
        
$currentId $parent[0]['cat_id'];

        
// get all categories on the same level as the parent
        
$tempParentId $ids[$tempParentId]['cat_parent_id'];
        foreach (
$categories as $category) {
            
// found one category on the same level as parent
            // put in $parent if it's not already in it
            
if ($category['cat_parent_id'] == $tempParentId && !in_array($category$parent)) {
                
$parent[] = $category;
            }
        }
        
        
// sort the category alphabetically
        
array_multisort($ids,SORT_ASC);
    
        
// merge parent and child
        
$n count($parent);
        
$navCat2 = array();
        for (
$i 0$i $n$i++) {
            
$navCat2[] = $parent[$i];
            if (
$parent[$i]['cat_id'] == $currentId) {
                
$navCat2 array_merge($navCat2$navCat);
            }
        }
        
        
$navCat $navCat2;
    }


    return 
$navCat;
}

/*
    Get all top level categories
*/
function getCategoryList()
{
    
$sql "SELECT cat_id, cat_name, cat_image
            FROM tbl_category
            WHERE cat_parent_id = 0
            ORDER BY cat_name"
;
    
$result dbQuery($sql);
    
    
$cat = array();
    while (
$row dbFetchAssoc($result)) {
        
extract($row);
        
        if (
$cat_image) {
            
$cat_image WEB_ROOT 'images/category/' $cat_image;
        } else {
            
$cat_image WEB_ROOT 'images/Aucune image dispo.jpg';
        }
        
        
$cat[] = array('url'   => $_SERVER['PHP_SELF'] . '?c=' $cat_id,
                       
'image' => $cat_image,
                       
'name'  => $cat_name);

    }
    
    return 
$cat;            
}

/*
    Fetch all children categories of $id. 
    Used for display categories
*/
function getChildCategories($categories$id$recursive true)
{
    if (
$categories == NULL) {
        
$categories fetchCategories();
    }
    
    
$n     count($categories);
    
$child = array();
    for (
$i 0$i $n$i++) {
        
$catId    $categories[$i]['cat_id'];
        
$parentId $categories[$i]['cat_parent_id'];
        if (
$parentId == $id) {
            
$child[] = $catId;
            if (
$recursive) {
                
$child   array_merge($childgetChildCategories($categories$catId));
            }    
        }
    }
    
    return 
$child;
}

function 
fetchCategories()
{
    
$sql "SELECT cat_id, cat_parent_id, cat_name, cat_image, cat_description
            FROM tbl_category
            ORDER BY cat_name, cat_parent_id "
;
    
$result dbQuery($sql);
    
    
$cat = array();
    while (
$row dbFetchAssoc($result)) {
        
$cat[] = $row;
    }
    
    return 
$cat;
}

?>
me salen todos los productos en todas las categorias.
Un product puede tener varias categorias y quando se elija una categoria, pues que salga todos los productos de esa categoria.
Pero visto que estoy muy verde, pues no se si tengo que incluir un array o una function para que haga el paripe.
Me sigues !?
Gracias por tu ayuda

Última edición por b0zZy; 04/02/2009 a las 03:04
  #4 (permalink)  
Antiguo 04/02/2009, 08:02
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 8 meses
Puntos: 574
Respuesta: Productos en Multiples Categorias

tbl_product
pd_id
cat_id
cat_id2
cat_id3

....

tbl_category
cat_id
cat_name
...

many
pd_id
cat_id
cat_id2
cat_id3
...

Parece que tenemos un arbol de categorias y que cada producto puede estar relacionado a varias ramas de categorias, es decir un producto puede tener varios trios de id de categoria (cat_id,cat_id2,cat_id3) eso nos lo permite la tabla many.

Con esa estructura sobran los campos cat_id de los tres niveles de en la tabla de productos, puesto que la relación producto categoria se hace atraves de la tabla many si la relacion fuera 1 a 1 luego si tendrian sentido y sobraria la tabla many.

Por lo anterior la base no estaria bien normalizada.

En cuanto a las funciones que me pasas, así por encima, tratan de categorias no de productos, por tanto no puedo ver donde tienes el error.

En cuanto a la query

Código:
SELECT tbl_product.pd_id, tbl_product.cat_id2, tbl_product.cat_id3, tbl_category.cat_id, 
CASE WHEN many.cat_id IS NULL 
THEN 'F'
ELSE 'T'
END AS selected
FROM tbl_category
CROSS JOIN tbl_product
LEFT JOIN many ON ( many.cat_id = tbl_product.cat_id
                          AND many.cat_id = tbl_product.cat_id ) 
WHERE (
tbl_product.cat_id = tbl_category.cat_id
)
ORDER BY `tbl_category`.`cat_id` ASC[...]';
no se porque repites la clausula que esta en rojo ni que indica [...]

Esa query da una lista de todos los productos y todas las categoria (CROSS JOIN=producto cartesiano) con un F o una T si existe la relacion producto categoria en cada caso, ademas nos da los tres campos innecesarios de la tabla productos.

Por tanto no da los productos de una categoria como pedias...?

Vamos por partes

Código:
SELECT P.pd_id,m.cat_id,m.cat_id2,m.cat_id3
FROM tbl_product P inner join many
            on p.pd_id=m.pd_id
esto nos da una lista de todos los productos con sus categorias (los productos estaran repetidos tantas veces como tripletas distintas de categorias tengan)


si agregamos a la consulta anterior un

where m.cat_id=cat_X

nos dara todos los productos el primer nivel de categoria sea igual a cat_X

where m.cat_id=cat_X or m.cat_id2=cat_X or m.cat_id3=cat_X

esto nos daria los productos que uno de sus tres niveles de categoria sea igual a cat_X

A tu preugunta: NO TE SIGO!!!

Quim
  #5 (permalink)  
Antiguo 04/02/2009, 08:30
Avatar de b0zZy  
Fecha de Ingreso: enero-2009
Ubicación: Francia
Mensajes: 28
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Productos en Multiples Categorias

Hola Quim,
Parece que si me sigues perfectamente !! Pero ahora el que no sigue soy yo.
Mira este es el product-functions.php
Código PHP:
function getProductDetail($pdId$catId)
{
    
    
$_SESSION['shoppingReturnUrl'] = $_SERVER['REQUEST_URI'];
    
    
// get the product information from database
    
$sql ="SELECT * FROM tbl_product
INNER JOIN tbl_category
ON tbl_product.cat_id = tbl_category.cat_id
WHERE pd_id = $pdId"
;

    
$result dbQuery($sql);
    
$row    dbFetchAssoc($result);
    
extract($row);
    
    
$row['pd_descriptif'] = nl2br($row['pd_descriptif']);
    
    if (
$row['pd_image']) {
        
$row['pd_image'] = WEB_ROOT 'images/product/' $row['pd_image'];
    } else {
        
$row['pd_image'] = WEB_ROOT 'images/Aucune image dispo.jpg';
    }
    
    
$row['cart_url'] = "cart.php?action=add&p=$pdId";
    
    return 
$row;            
}



?> 
y este mi productlist.php
Código PHP:
<?php
//$productList    = getProductList($catId);
$children array_merge(array($catId), getChildCategories(NULL$catId));
$children ' (' implode(', '$children) . ')';

$sql "SELECT pd_id, pd_auteur, pd_titre, pd_editeur, cat_name, pd_isbn, pd_descriptif, pd_price, pd_etat, pd_thumbnail, pd_qty, c.cat_id, c.cat_name
        FROM tbl_product pd, tbl_category c
        WHERE pd.cat_id = c.cat_id AND pd.cat_id IN $children 
        ORDER BY pd_titre ASC"
;
$result     dbQuery(getPagingQuery($sql$productsPerPage));
$pagingLink getPagingLink($sql$productsPerPage"c=$catId");
$numProduct dbNumRows($result);

// the product images are arranged in a table. to make sure
// each image gets equal space set the cell width here
$columnWidth = (int)(100 $productsPerRow);?>
<script src="library/sorttable.js"></script>
<link href="shop.css" rel="stylesheet" type="text/css" />
<link href="../admin/include/admin.css" rel="stylesheet" type="text/css" />

<style type="text/css">
<!--
.Estilo9 {
    color: #CCCCCC;
    font-weight: bold;
}
-->
</style>
<table border="1" align="center" bordercolor="#800000" class="sortable">
<!--Table Head -->
<thead>
<tr bgcolor="#800000">
<th height="31" class="Estilo9">Titre(s)</th>
<th class="Estilo9">Auteur(s)</th>
<th class="Estilo9">Image</th>
<th class="Estilo9">Prix/&Eacute;tat</th>
</tr>
</thead>

  <?php 
if ($numProduct ) {

    
$i 0;
    while (
$row dbFetchAssoc($result)) {
        
extract($row);
        if (
$pd_thumbnail) {
            
$pd_thumbnail WEB_ROOT 'images/product/' $pd_thumbnail;
        } else {
            
$pd_thumbnail WEB_ROOT 'images/Aucune image dispo.jpg';
        }
    
        if (
$i $productsPerRow == 0) {
            echo 
'<tr>';
        }

        
// format how we display the price
        
$pd_price displayAmount($pd_price);
        
        echo 
"<td width=\"50%\" align=\"center\"><a href=\"" $_SERVER['PHP_SELF'] . "?c=$catId&p=$pd_id" "\">$pd_titre
        <td with=\"10%\"align=\"center\"><a href=\"" 
$_SERVER['PHP_SELF'] . "?c=$catId&p=$pd_id" "\">$pd_auteur
        <td width=\"10%\" align=\"center\"><a href=\"" 
$_SERVER['PHP_SELF'] . "?c=$catId&p=$pd_id" "\"><img src=\"$pd_thumbnail\" border=\"0\" align=\"absmiddle\">
        <td width=\"10%\" align=\"center\"><br>$pd_price"
?>&nbsp;€<br />
<?php echo "$pd_etat"?>
<?php
        
// if the product is no longer in stock, tell the customer
        
if ($pd_qty <= 0) {
            echo 
"<br><u>Pas Disponible";
        }
        
        echo 
"</td>\r\n";
    
        if (
$i $productsPerRow == $productsPerRow 1) {
            echo 
'</tr>';
        }
        
        
$i += 1;
    }
    
    if (
$i $productsPerRow 0) {
        echo 
'<td colspan="' . ($productsPerRow - ($i $productsPerRow)) . '">&nbsp;</td>';
    }
    
} else {
?>
<tr>
    <td height="31" colspan="5" align="center">
      <span class="errorMessage">Aucune</span> 
      <?php    
}    
?>
</table>
<p align="center"><?php echo $pagingLink?></p>
<p align="center"><span style="width:500px">
  <input name="retour" type="submit" class="bluebox" id="retour" onclick="window.history.back();" value="Retour" />
</span></p>
Como lo puedo poner para que quando un usuario en la web elija una categoria, salgan todos los resultados de esa categoria. No se si es donde lo tengo mal pero yo guardo las categorias de los productos en la tbl_product como cat_id, cat_id2 y cat_id3.
Por ejemplo, tengo un livro X con las categorias A, B y C, la A es cat_id, la B es cat_id2 y la C es cat_id3.
Si voy a la categoria A esta el livro X bien, pero si lo busco en las categorias B o C, no me aparece.
A ver si me echas un cable que esto me tiene amargao .

Última edición por b0zZy; 04/02/2009 a las 08:59
  #6 (permalink)  
Antiguo 04/02/2009, 10:10
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 8 meses
Puntos: 574
Respuesta: Productos en Multiples Categorias

El primer caso: function getProductDetail($pdId, $catId)

SELECT * FROM tbl_product
INNER JOIN tbl_category
ON tbl_product.cat_id = tbl_category.cat_id
WHERE tbl_product.pd_id = $pdId

en este caso nos dará el producto identificado por la variable $pdId. Totdos los campos de la tabla producto y todos los de categoria.

La funcion recibe como parametro otra variable ($catId) pero no la usa para nada?

La funcion a parte de mostrar la imagen del producto parece que agrega el producto a un carro de compra....

por tanto esto no tiene nada que ver con categorias.

Segundo caso:productlist.php

No tenemos function por tanto no se que parametros usará pero anlicemos el SQL

Código:
SELECT pd_id, pd_auteur, 
             pd_titre, pd_editeur, 
             cat_name, pd_isbn, 
             pd_descriptif, pd_price, 
             pd_etat, pd_thumbnail, 
             pd_qty, c.cat_id, c.cat_name
   FROM tbl_product pd, tbl_category c
   WHERE pd.cat_id = c.cat_id AND pd.cat_id IN $children 
   ORDER BY pd_titre ASC
Supongo que los campos que no tienen alias vienen de productos y los del alias c obvimente vinen de category

Esto nos da una lista ordenada por titulo de los libros cuyo primer identificador de categoria esta en $children

Bingo !! $children ha de tener la siguiente forma (cat_X,cat_Y,cat_Z,...) por tanto nos dara la lista de productos de un grupo de categorias, pero solo mirando el primer identificador ...

$children = ' (' . implode(', ', $children) . ')';

correcto tiene la forma que tiene que tener!!!

Cita:
Como lo puedo poner para que quando un usuario en la web elija una categoria, salgan todos los resultados de esa categoria. No se si es donde lo tengo mal pero yo guardo las categorias de los productos en la tbl_product como cat_id, cat_id2 y cat_id3.
Si la realción de producto/categoria es n a n luego SI ESTA MAL

Si los productos pueden tener una, dos o tres categorias, o lo que es lo mismo como maximo tres categrias, no seria un gran diseño pero podria funcionar.

Cita:
Por ejemplo, tengo un livro X con las categorias A, B y C, la A es cat_id, la B es cat_id2 y la C es cat_id3.
Luego cat_id='A' , cat_id2='B' y cat_id3='C' si?

Cita:
Si voy a la categoria A esta el livro X bien, pero si lo busco en las categorias B o C, no me aparece.
Tu mismo te responderas... Como vas a la categoria A?

where cat_id='A' ---> funciona!!!!

where cat_id='B'----> no funciona
where cat_id='C'----> no funciona

recuerda lo que has dicho cat_id='A' , cat_id2='B' y cat_id3='C'

Por lo que yo se si cat_id='A' es imposible que al mismo tiempo sea B o C

Intenta a ver si

where cat_id2='B'----> funciona?
where cat_id3='C'----> funciona?

Suerte....

Quim
  #7 (permalink)  
Antiguo 04/02/2009, 11:42
Avatar de b0zZy  
Fecha de Ingreso: enero-2009
Ubicación: Francia
Mensajes: 28
Antigüedad: 15 años, 10 meses
Puntos: 0
De acuerdo Resulto Gracias Quim

Hola una vez mas Quim,
Bueno pues si que era mas simples de lo que me parecia !! Simplesmente he cambiado
Código PHP:
$sql "SELECT pd_id, pd_auteur, pd_titre, pd_editeur, cat_name, pd_isbn, pd_descriptif, pd_price, pd_etat, pd_thumbnail, pd_qty, c.cat_id, c.cat_name 
        FROM tbl_product pd, tbl_category c 
        WHERE pd.cat_id = c.cat_id AND pd.cat_id IN $children  
        ORDER BY pd_titre ASC"

A
Código PHP:
$sql "SELECT pd_id, pd_auteur, pd_titre, pd_editeur, cat_name, pd_isbn, pd_descriptif, pd_price, pd_etat, pd_thumbnail, pd_qty, c.cat_id, c.cat_name
        FROM tbl_product pd, tbl_category c
        WHERE pd.cat_id = c.cat_id AND pd.cat_id IN $children
        OR  pd.cat_id2 = c.cat_id AND pd.cat_id2 IN $children
        OR pd.cat_id3 = c.cat_id AND pd.cat_id3 IN $children
        ORDER BY pd_titre ASC"

Y ahora va de maravilla !!
Gracias Quim !!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 23:10.