2

Hi I am new in php and for my study project trying to resolve some challenges

I have 3 tables "products", "categories", "product_to_categories"

products table:

product_id    product_name    product_price    product_img    product_link    date
1             item1_name      item1_price      item1_img      item1_link      item1_date
2             item2_name      item2_price      item2_img      item2_link      item2_date

categories table:

category_id    category_name    
1              category1_name      
2              category2_name     
3              category3_name     

and product_to_categories table:

relation_id    product_id    category_id    
1              product1_id   category1_id     
2              product1_id   category2_id      
3              product2_id   category1_id  
4              product2_id   category3_id  

I am trying to get 2 things:

  1. write a list of all products together with the all categories names (no ids) they belong to.
  2. list only those products that belong to the given categories

Unfortunately, I don't know how to approach this.

show_products.php:

<?php
$per_page=100;

    if(isset($_GET['page'])){
        $page = $_GET['page'];
    }else{
        $page=1;
    }
    $start_from = ($page-1) * $per_page;

    $get_products = "SELECT * FROM products ORDER BY 1 DESC LIMIT $start_from,$per_page";

    $run_products = mysqli_query($conn,$get_products);

    while($row_products=mysqli_fetch_array($run_products)){

        $pro_id = $row_products['product_id'];
        $pro_name = $row_products['product_name'];
        $pro_price = $row_products['product_price'];
        $pro_img = $row_products['product_img'];
        $pro_link = $row_products['product_link'];
        $pro_date = $row_products['date'];

        echo "
         <tr>
            <td style='width: 70px'>$pro_id</td>
            <td><img src='../p_img/$pro_img' style='width:70px;'></td>
            <td>$pro_name</td>
            <td>ok. $pro_price zł</td>
            <td>$pro_link</td>
            <td></td>
            <td>$pro_date</td>
          </tr>
        ";
    }
?>

2
  • The best approach you statet in the title of the question: use JOIN. The names of the fields even allow MySQLs NATURAL JOIN, which is the easiest way of connecting tables. Commented May 29, 2020 at 14:08
  • this is solution from very similar problem => stackoverflow.com/a/33306132/10103789 Commented May 29, 2020 at 14:12

2 Answers 2

3

This is really about the SQL language and learning how to use it. Hopefully you have a GUI for your database such as PhpMyAdmin or HeidiSQL, because it is often easier to use that when writing SQL code.

Assuming you have these tables:

CREATE TABLE products
(
    product_id int PRIMARY KEY,
    product_name varChar(255)   
);

CREATE TABLE categories
(
    category_id int PRIMARY KEY,
    category_name varChar(255)
);

CREATE TABLE product_to_categories
(
    product_id int,
    category_id int,
   FOREIGN KEY (product_id) REFERENCES products(product_id),
   FOREIGN KEY (category_id) REFERENCES categories(category_id)
);

With this sample data:

INSERT INTO products VALUES (1, 'Product 1'), (2, 'Product 2');
INSERT INTO categories VALUES (1, 'Category 1'), (2, 'Category 2');
INSERT INTO product_to_categories VALUES (1,1), (2,1), (2,2);

You can use this long-form query to get the data out:

SELECT
    P.*,
    C.category_name
FROM
    products P
JOIN 
    product_to_categories PC
    ON
    P.product_id = PC.product_id
JOIN
    categories C
    ON
    PC.category_id = C.category_id

Which returns

1   Product 1   Category 1
2   Product 2   Category 1
2   Product 2   Category 2

However, because you are using the same columns names across your join table, you can also use the NATURAL JOIN command to produce the same

SELECT
    P.*,
    C.category_name
FROM
    products P
NATURAL JOIN
    categories C
NATURAL JOIN
    product_to_categories

To get the product from a single category you could use:

SELECT
    *
FROM
    products P
NATURAL JOIN
    product_to_categories PC
WHERE
    PC.category_id = 2

which returns

2   Product 2   2
Sign up to request clarification or add additional context in comments.

2 Comments

thanks a lot! If I can ask you for one more thing. Is there any SQL operator that can merge results? I mean that it will show: "1 Product 1 Category 1 (new row) 2 Product 2 Category 1, Category 2" except "1 Product 1 Category 1 (new row) 2 Product 2 Category 1 (new row) 2 Product 2 Category 2 (new row)" or should I do it on frontend side?
@Elijah, I'm not sure I understand your question. It might be better to ask a new question on this site where you can format what you are hoping to get. You can reference this question which will help people with some background.
0

For the first question: You should use the JOIN clause to be able to relate products to categories through their id:

SELECT
    p.product_name,
    c.category_name,
FROM
    products p
JOIN
    products_categories pc ON p.product_id = pc.product_id
JOIN
    categories c ON pc.category_id = c.category_id

For the second question: When you relate two tables, you can filter the results of the table you are joining by adding a where clause in the join:

SELECT
    p.product_name
FROM
    products p
JOIN
    products_categories pc ON p.product_id = pc.product_id AND pc.category_id = 1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.