I run a shopping cart where products can have additional options. For example, product1 can have multiple options like:
-
Sizes:
s,m,l,xl -
Color:
red,blue,green
The default product is stored in customers_basket.
The additional chosen items are stored in customers_basket_attributes.
In both tables I insert a unique key called products_unique_id.
This is to identify whenever a customer adds another product with the same option, if so
I simply need to update the quantity field of the customers_basket table.
If the user inserts the same product but with different options, the products_unique_id changes.
The following query doesn’t work:
SELECT * FROM
customers_basket_attributes cba,
customers_basket cb
WHERE
cba.products_id = cb.products_id
AND
cba.products_unique_id = cb.products_unique_id
AND customers_id="1"
However, this query works:
SELECT * FROM
customers_basket cb,
products p,
products_description pd
WHERE
cb.products_id = p.products_id
AND
cb.products_id = pd.products_id
AND customers_id="1"
Also this works:
SELECT * FROM
customers_basket_attributes cba,
products p,
products_description pd
WHERE
cba.products_id = p.products_id
AND
cba.products_id = pd.products_id
AND customers_id="1"
Database Structure & Records
The following is the database structure and records needed to test the queries above:
DROP TABLE IF EXISTS customers_basket;
CREATE TABLE customers_basket (
customers_basket_id INTEGER PRIMARY KEY ASC,
customers_id int NOT NULL,
products_id int NOT NULL,
products_unique_id tinytext NOT NULL,
customers_basket_quantity int(2) NOT NULL,
final_price decimal(15,4),
customers_basket_date_added datetime
);
DROP TABLE IF EXISTS customers_basket_attributes;
CREATE TABLE customers_basket_attributes (
customers_basket_attributes_id INTEGER PRIMARY KEY ASC,
customers_id int NOT NULL,
products_id int NOT NULL,
products_unique_id tinytext NOT NULL,
products_options_id int NOT NULL,
products_options_txt varchar(64) NOT NULL default '',
products_options_value_id int NOT NULL,
products_options_value_txt varchar(64) NOT NULL default ''
);
In addition, I’ve included the tables below even though they shouldn’t be needed to test the problem query.
DROP TABLE IF EXISTS products;
CREATE TABLE products (
products_id int NOT NULL,
products_quantity int(4) NOT NULL,
products_model varchar(12),
products_image varchar(64),
products_price decimal(15,4) NOT NULL,
products_date_added datetime NOT NULL,
products_last_modified datetime,
products_date_available datetime,
products_weight decimal(5,2) NOT NULL,
products_status tinyint(1) NOT NULL,
products_tax_class_id int NOT NULL,
manufacturers_id int NULL,
products_ordered int NOT NULL default '0',
PRIMARY KEY (products_id)
);
DROP TABLE IF EXISTS products_description;
CREATE TABLE products_description (
products_id int NOT NULL,
language_id int NOT NULL default '1',
products_name varchar(64) NOT NULL default '',
products_description text,
products_url varchar(255) default NULL,
products_viewed int(5) default '0',
PRIMARY KEY (products_id,language_id)
);
INSERT INTO customers_basket_attributes VALUES (1,1,1,1{4}1{3}5{5}10,4,Memory,1,4 mb);
INSERT INTO customers_basket_attributes VALUES (2,1,1,1{4}1{3}5{5}10,3,Model,5,Value);
INSERT INTO customers_basket_attributes VALUES (3,1,1,1{4}1{3}5{5}10,5,Version,10,Download: Windows - English);
INSERT INTO customers_basket_attributes VALUES (4,1,2,2{4}3{3}6,4,Memory,3,16 mb);
INSERT INTO customers_basket_attributes VALUES (5,1,2,2{4}3{3}6,3,Model,6,Premium);
INSERT INTO customers_basket VALUES(1,1,1,1{4}1{3}5{5}10,1,0,DATETIME('NOW'));
INSERT INTO customers_basket VALUES(2,1,2,2{4}3{3}6,2,0,DATETIME('NOW'));
INSERT INTO products VALUES (1,32,'MG200MMS','matrox/mg200mms.gif',299.99, DATETIME('NOW'),null,null,23.00,1,1,1,0);
INSERT INTO products VALUES (2,32,'MG400-32MB','matrox/mg400-32mb.gif',499.99, DATETIME('NOW'),null,null,23.00,1,1,1,0);
INSERT INTO `products_description` VALUES(1, 1, 'Matrox G200 MMS', '', 'www.matrox.com/mga/products/g200_mms/home.cfm', 0);
INSERT INTO `products_description` VALUES(2, 1, 'Matrox G400 32MB', '', 'www.matrox.com/mga/products/mill_g400/home.htm', 0);
UPDATE: I just discovered it fails between table customers_basket_attributes and customers_basket.
Table products and products_description work alright if check them with the other 2 tables independently.
** Because of principle, I’ve decided @Jonathan Leffler deserves the bounty. Not only for the his answer, also for his efforts trying to let me understand his given answer.So please do not try to earn this bounty. If I stay blocked from SO, I want to feel confident in my last action **
Your table organization is a bit odd, it seems, because you would not normally expect to find both
Customers_BasketandCustomers_Basket_Attributescontaining theproducts_idcolumn. However, taking that at face value, and using the modern JOIN notation (use that always, not the old SQL-86 join notations), you might be after:However, it much more likely that you need to join Customers_Basket (CB) and Customers_Basket_Attributes (CBA) on other (as yet unidentified) columns, such as
CBA.Basket_ID = CB.Basket_ID.Schema Analysis
Because you’ve not shown us sufficient of the table schemas, nor have you shown us what you have tried that more or less worked, it is hard to help you more.
You’ve now shown us the table schemas, which is a start, but the schema is still somewhat mystifying. In particular, you’ve not shown the foreign key relationships between the Customers_Basket (CB) and Customers_Basket_Attributes (CBA) tables.
You have, it seems:
This is somewhat contorted.
Under what seems to me like a reasonable interpretation of what these might represent, I would expect a customer to have (over time) multiple baskets CB. Each basket can have, potentially, multiple items (maybe one, maybe many). The item information would be in the CBA table. This would suggest a schema such as:
This leaves most of the product description in the product description tables. It leaves you with a simpler customer basket table – you would probably add other fields to it. And the customers basket attributes table is far simpler too.
With this structure, you might write the SQL as:
I’ve not studied your product and product description tables to see how well they work together.