我经营一个购物车,产品可以有其他选择。例如, product1 可以有多个选项,如:
大小: S,M,L,XL
颜色: 红色,蓝色,绿色
默认产品存储在customers_basket
。
其他所选项目存储在customers_basket_attributes
。
在两个表中,我插入一个名为products_unique_id
的唯一键。
这是为了识别客户何时添加具有相同选项的其他产品,如果是的话
我只需要更新customers_basket
表的数量字段。
如果用户插入相同的产品但具有不同的选项,products_unique_id
会发生变化。
以下查询不起作用:
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"
但是,此查询有效:
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"
这也有效:
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"
数据库结构&记录
以下是测试上述查询所需的数据库结构和记录:
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 ''
);
此外,我已经包含了下表,即使不需要它们来测试问题查询。
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);
更新:我刚发现它在表customers_basket_attributes
和customers_basket
之间失败。
表products
和products_description
可以正常工作,如果与其他2个表单独检查它们。
**由于原则,我决定@Jonathan Leffler应得的赏金。不仅是因为他的答案,也是因为他努力让我理解他的答案。所以请不要试图获得这笔赏金。如果我对SO保持封锁,我希望对我的最后一次行动充满信心**
答案 0 :(得分:6)
您的表格组织似乎有点奇怪,因为您通常不会期望找到包含Customers_Basket
列的Customers_Basket_Attributes
和products_id
。但是,从表面上看,使用现代的JOIN表示法(总是使用旧的SQL-86连接符号),你可能会追求:
SELECT cb.*, cba.*, p.*, pd.*
FROM customers_basket AS cb
JOIN customers_basket_attributes AS cba ON cb.products_id = cba.products_id
JOIN products AS p ON cb.products_id = p.products_id
JOIN products_description AS pd ON cb.products_id = pd.products_id
WHERE cb.customers_id = "1"
但是,您更有可能需要在其他(尚未识别的)列上加入Customers_Basket(CB)和Customers_Basket_Attributes(CBA),例如CBA.Basket_ID = CB.Basket_ID
。
因为您没有向我们展示足够的表格模式,也没有向我们展示您尝试过或多或少的工作,所以很难为您提供更多帮助。
您现在向我们展示了表格模式,这是一个开始,但模式仍然有些神秘。特别是,您没有显示Customers_Basket(CB)和Customers_Basket_Attributes(CBA)表之间的外键关系。
你有,似乎:
CB CBA
customers_basket_id (PK) customers_basket_attributes_id (PK)
customers_id customers_id
products_id products_id
products_unique_id products_unique_id
customers_basket_quantity products_options_id
final_price products_options_value_id
customers_basket_date_added products_options_value_txt
这有点扭曲。
在我看来,对这些可能代表什么的合理解释,我希望客户(随着时间的推移)有多个篮子CB。每个篮子可能有多个项目(可能是一个,也许很多)。项目信息将在CBA表中。这将建议一个模式,如:
CREATE TABLE customers_basket
(
customers_basket_id INTEGER PRIMARY KEY ASC,
customers_id INTEGER NOT NULL REFERENCES Customers,
customers_basket_date_added DATETIME
);
CREATE TABLE customers_basket_attributes
(
customers_basket_attributes_id INTEGER PRIMARY KEY ASC,
customers_basket_id INTEGER NOT NULL REFERENCES Customers_Basket,
products_id INTEGER NOT NULL REFERENCES Products,
quantity INTEGER NOT NULL
);
这会将大部分产品说明留在产品说明表中。它为您提供了一个更简单的客户购物篮表 - 您可能会添加其他字段。客户篮子属性表也简单得多。
使用此结构,您可以将SQL编写为:
SELECT c.*, b.*, a.*, p.*, d.*
FROM customers AS c
JOIN customers_basket AS b ON c.customers_id = b.customers_id
JOIN customers_basket_attributes AS a ON b.customers_basket_id = a.customers_basket_id
JOIN products AS p ON a.products_id = p.products_id
JOIN products_description AS p ON p.products_id = d.products_id
WHERE c.customers_id = "1"
我没有研究过您的产品和产品说明表,看看它们如何协同工作。
答案 1 :(得分:2)
我不是100%肯定我明白,但是这个怎么样:
SELECT * FROM
customers_basket cb,
products p,
products_description pd,
customers_basket_attributes cba
WHERE
cb.products_id = p.products_id
AND
cb.products_id = pd.products_id
AND
cba.products_id = cb.products_id
AND customers_id="1"