Question : SQL query help for an online shop

Hello,

I would very much appreciate some help with a query to get results from an online shop Database which I'll try explain like so:

The end result is I need to return the product info including the lowest price of the price component (1 product may have multiple component prices for different sizes etc) and ones which are in stock but also some items if out of stock may have a flag which can treat it as its in stock.

I have the table structures as indicated in the code attached below:

This is my original query which is really no good as I grouped it by ID to remove the duplicate entries returned with the Join, but what it returns is the product information with a price included:

SELECT p.ID, p.item, p.category_name, p.pic, p.short_description, p.full_description,  p.featured, p.show_on_site, pc.component_price, pc.ID pcID, pc.stock_level stock
    FROM products p
    LEFT JOIN product_component pc ON pc.product_id = p.ID
    WHERE p.live='1'
    AND p.category_name = '8'
    GROUP BY ID
    ORDER BY order_on_site ASC, ID ASC

This produces: (with some columns removed)

+----+---------------------+--------------------+------------------+-----------------------+------+--------+
| ID  | item                   | category_name | show_on_site | component_price | pcID | stock |
+----+---------------------+--------------------+------------------+-----------------------+------+--------+
|  3  | Lumo                  | 8                       |                     1 | 250.00                  |     2 |        0 |
|  4  | Traditional Blue  | 8                       |                      1 | 250.00                  |    4 |      43 |
|  6  | Bronze Ghost     | 8                       |                      1 | 250.00                  |    6 |      24 |
| 15 | Purple/Orange   | 8                       |                      1 | 250.00                  |   12 |       0 |
+----+---------------------+--------------------+-------------------+-----------------------+------+-------+

which seems to take the first component ID and use that in the price, this does not care for whether the price product_component has stock or not.

The bad thing I realised I did is grouped it by ID to only get single results ;)

Either way the result I really need would be based on the following rules:

If a product is not in stock but has the show when no stock flag checked (stock_level =0 AND show_when_no_stock =1)
then it would still be counted as available to purchase.

If a product is not in stock but DOES NOT have the show when no stock flag checked (stock_level =0 AND show_when_no_stock < 1)
Then it should not be returned.

the price returned should be the lowest price in the product components, so in the table below, the product_component with ID=7 should really be returned.


So this is what I should get returned (if I queried from the data in the attached code):

+----+---------------------+--------------------+------------------+-----------------------+------+--------+
| ID  | item                   | category_name | show_on_site | component_price | pcID | stock |
+----+---------------------+--------------------+------------------+-----------------------+------+--------+
|  3  | Lumo                  | 8                       |                     1 | 250.00                  |     2 |        0 |
|  4  | Traditional Blue  | 8                       |                      1 | 250.00                  |    4 |      43 |
|  6  | Bronze Ghost     | 8                       |                      1 | 100.00                  |    6 |      20 |
+----+---------------------+--------------------+-------------------+-----------------------+------+-------+

so really the only thing thats taken out is the product ID with 15 as theres no stock and show_when_no_stock is empty.
The actual stock amount doesn't really need to be returned its more for demonstration in this question...

Please fire away any questions to clarify what I'm trying to do, I'm reaching the limits of my SQL to do this so I am looking forward to learning some more :)

My Language is Perl so if it needs to happen with perl code too then thats also fine,

Tim
Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
products Table: (I've not included a few columns as they aren't relevant) 
mysql> SELECT ID, item, featured, show_on_site, order_on_site FROM products WHERE live = 1 AND category_name = '8' LIMIT 10;
+----+------------------+----------+--------------+---------------+
| ID | item             | featured | show_on_site | order_on_site |
+----+------------------+----------+--------------+---------------+
|  3 | Lumo             |        1 |            1 |            10 |
|  4 | Traditional Blue |        1 |            1 |            20 |
|  6 | Bronze Ghost     |        1 |            1 |            30 |
| 15 | Purple/Orange    |        1 |            1 |            40 |
+----+------------------+----------+--------------+---------------+ 
 
products_components Table 
mysql> select ID, product_id p_id, component_title, component_price, stock_level,  show_when_no_stock FROM product_component WHERE live=1 AND product_id IN (SELECT ID FROM products WHERE category_name =8);
+----+------+-----------------+-----------------+-------------+--------------------+
| ID | p_id | component_title | component_price | stock_level | show_when_no_stock |
+----+------+-----------------+-----------------+-------------+--------------------+
|  2 |    3 | T9-3 Lumo       | 250.00          |           0 |                  1 |
|  4 |    4 | T9              | 250.00          |          43 |                  1 |
|  5 |    5 | T9              | 250.00          |          15 |               NULL |
|  6 |    6 | T6              | 250.00          |          24 |                  1 |
|  7 |    6 | T6 b            | 100.00          |          20 |                  1 |
|  8 |    6 | T6 c            | 320.00          |          11 |                  1 |
| 11 |   14 |                 | 250.00          |          50 |               NULL |
| 12 |   15 | T9              | 250.00          |           0 |               NULL |
+----+------+-----------------+-----------------+-------------+--------------------+

Answer : SQL query help for an online shop

select ID, product_id p_id, component_title, component_price, stock_level,  show_when_no_stock
FROM product_component WHERE live=1 AND product_id IN (SELECT ID FROM products WHERE category_name =8)
and stock_level!=0 and show_when_no_stock is not null

Get the result and do it in Perl if the same ID is coming then component_price*stock_level check this and find the lowest
Random Solutions  
 
programming4us programming4us