2

I have a problem in adding price, size and stocks. How can I add price, stocks and size without duplicating?

Here is my database structure:

tblproduct

tblproduct

tblextension

tblextension

PS: tblproduct product_id and tblproduct_extension product_id are the same.


Here is the result after I add price, stocks and price. As you can see there are two 'Nike Lebron 15 Ghost'.

products

query

SELECT * FROM tblproduct LEFT JOIN tblproduct_extension ON tblproduct_extension.product_id = tblproduct.product_id;

ajax

//Show modal for adding size, price and stocks
function add_product_extension() {
    $('#product_add_extension').click(function(e){
        var product_id = $('#product_id').val();
        var product_price = $('#product_price').val();
        var product_stocks = $('#product_stocks').val();
        var product_size = $('#product_size').val();
        $.ajax({
            type: 'POST',
            url: '../admin/class.php',
            data: {product_id:product_id,product_price:product_price,product_stocks:product_stocks,product_size:product_size},
            success:function(data) {
                $('#addSize').modal('hide');
            }
        });
    });
}

class.php

    //Add size, price, stocks
    if(isset($_POST['product_id'])) {
        $product_price = $_POST['product_price'];
        $product_stocks = $_POST['product_stocks'];
        $product_size = $_POST['product_size'];
        $product_id = $_POST['product_id'];

        $insert_query = "INSERT INTO tblproduct_extension (product_stocks, product_price, product_size, product_id)VALUES('$product_stocks', '$product_price', '$product_size', '$product_id')";
        $query = mysqli_query($db_conn, $insert_query);
    }

Code to display products

    //Get Products by ID
    function get_products() {
        GLOBAL $db_conn;
        $id = $_GET['id'];
        $search_query= "SELECT * FROM tblproduct LEFT JOIN tblproduct_extension ON tblproduct_extension.product_id = tblproduct.product_id WHERE tblproduct.segment_id='$id'";
        $query = mysqli_query($db_conn, $search_query);

        while ($row = mysqli_fetch_array($query)) {
            ?>
                <div class="products">
                    <a href="details.php?view_product=<?=$row['product_id']?>&id=<?=$row['segment_id']?>"><img class="img_product" src="../admin/<?=$row['product_image']?>" alt="<?=$row['product_name']?>"></a>
                    <?php if($row['product_stocks'] == 0) {?>
                        <span class="stock-label">SOLD OUT</span>
                    <?php } ?>
                    <h4><?=$row['product_name']?></h4>
                    <h3>&#8369;<?=number_format($row['product_price'], 2)?></h3>
                </div>
            <?php
        }
        return $row;
    }
DarkBee
  • 16,592
  • 6
  • 46
  • 58
Yeezus
  • 57
  • 8
  • See ON DUPLICATE KEY – Strawberry Nov 15 '17 at 08:38
  • SELECT * FROM tblproduct LEFT JOIN tblproduct_extension ON DUPLICATE KEY UPDATE tblproduct_extension.product_id = tblproduct.product_id; Check my query. – Yeezus Nov 15 '17 at 08:47
  • You cannot update inside a select – Strawberry Nov 15 '17 at 08:49
  • How? What should I do? – Yeezus Nov 15 '17 at 08:50
  • To answer this part of your question "How can I add price, stocks and size without duplicating?", always do a select query before inserting any new data in your class.php. If there is result from the select query, you know that the $product_id exists. E.g., "SELECT * FROM tblproduct_extension WHERE product_id = '" . $product_id . "'"; – louisecode Nov 15 '17 at 08:52
  • Check your data. You have two size (7 and 11) for this product (ID 8, Nike Lebron 15 Ghost) in table tblextension. So it's normal if its display twice. – Camille Nov 15 '17 at 08:55
  • as louisecode sates, you create a duplicate entry in your `tblproduct_extension` table because you don't test if already exists. The left join then combines them and outputs logically 2 results. Use `UPDATE` when the entry already exists – Kaddath Nov 15 '17 at 08:55
  • What if I update the product_id(8), assume that the product_id(8) will be (9) so if I add product size, stocks and price on product_id(8), the price, stocks, size will be added on product_id(9). I think it's not correct. – Yeezus Nov 15 '17 at 09:06
  • so it will be added on Nike Lebron 11 Metallic Silver, if I update the product_id. – Yeezus Nov 15 '17 at 09:14
  • 1
    these are 2 different problems. For your last comment: unique ids are not really meant to be updated, and if you do it, of course you need to change every reference to this id in the other tables that mention this id. What we are talking is that when you add a row to `tblproduct_extension`, you should check before that there is not already one for the current `product_id`, because if you insert a second one, you will have two conflicting sets of values for your stock, price etc. Actually `product_id` in `tblproduct_extension` should be set to `UNIQUE` – Kaddath Nov 15 '17 at 09:29
  • louisecode's suggestion is misguided. See about race conditions. – Strawberry Nov 15 '17 at 10:00
  • What should I do? – Yeezus Nov 15 '17 at 10:27
  • @Strawberry how is this situation a specific race competition problem? (apart from all websites over the web where a field can be updated by admin while a user requests a display). Are you suggesting the OP should create duplicate entries just on the sole purpose to avoid race situation? You should explain a bit why, and maybe offer a solution or clues, or else your comment will just confuse the OP IMO. – Kaddath Nov 15 '17 at 13:24

2 Answers2

2
$search_query= "SELECT DISTINCT * FROM tblproduct LEFT JOIN tblproduct_extension ON tblproduct_extension.product_id = tblproduct.product_id WHERE tblproduct.segment_id='$id'";

The SELECT DISTINCT statement is used to return only distinct (different) values.

If you don't want duplicates you can trim them from your query.

pr1nc3
  • 8,108
  • 3
  • 23
  • 36
1

As you can have multiple product_size, you can display also this information with product name

...
<h4><?=$row['product_name']?> - Size <?=$row['product_size']?></h4>
...

You can do a bit more complex query for achieve what you want (function get_products).

First Select only unique couple of product/extension, with smallest key of extension. From this, you do a second select who fetch data to display.

Those queries were not tested, but that give an idea.

With GROUP BY

-- 2. After you select your data with unique id get from sub query
SELECT      p.*, pe.*
FROM        tblproduct p
JOIN        (
            -- 1. First select your product_id and smallest product_extension_id
            SELECT      p.product_id, 
                        MIN(pe.product_extension_id) as product_extension_id
            FROM        tblproduct p
            LEFT JOIN   tblproduct_extension pe
            ON          pe.product_id = p.product_id 
            WHERE       p.segment_id='$id'
            GROUP BY    p.product_id
) product_unique
JOIN        tblproduct_extension pe
ON          pe.product_extension_id = product_unique.product_extension_id
WHERE       p.product_id = product_unique.product_id            

With DISTINCT

-- 2. After you select your data with unique id get from sub query
SELECT      p.*, pe.*
FROM        tblproduct p
JOIN        (
            -- 1. First select your product_id and smallest product_extension_id
            SELECT      DISTINCT
                        p.product_id, 
                        MIN(pe.product_extension_id) as product_extension_id
            FROM        tblproduct p
            LEFT JOIN   tblproduct_extension pe
            ON          pe.product_id = p.product_id 
            WHERE       p.segment_id='$id'
) product_unique
JOIN        tblproduct_extension pe
ON          pe.product_extension_id = product_unique.product_extension_id
WHERE       p.product_id = product_unique.product_id            
Camille
  • 2,439
  • 1
  • 14
  • 32
  • Thanks for this. But I want only one Lebron 15 Ghost to be displayed. – Yeezus Nov 15 '17 at 09:09
  • @Yeezus, I add another way to solve your issue, maybe that can help. Its base one answer [here](https://stackoverflow.com/questions/15626493/left-join-only-first-row) – Camille Nov 20 '17 at 09:01
  • Error: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'dbshopping.p.product_id'; this is incompatible with sql_mode=only_full_group_by – Yeezus Dec 08 '17 at 13:06
  • @Yesszus Perfect! Glad to know you make it works! :-) I added `GROUP BY` on First query. Is it what you did for make this query working? – Camille Dec 11 '17 at 09:08