我经营一个购物车,产品可以有其他选择.例如,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"
Run Code Online (Sandbox Code Playgroud)
但是,此查询有效:
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"
Run Code Online (Sandbox Code Playgroud)
这也有效:
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"
Run Code Online (Sandbox Code Playgroud)
数据库结构和记录
以下是测试上述查询所需的数据库结构和记录:
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 ''
);
Run Code Online (Sandbox Code Playgroud)
另外,我已经包含了下面的表格,即使它们不需要测试问题查询.
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);
Run Code Online (Sandbox Code Playgroud)
更新:我刚发现它在表customers_basket_attributes和表之间失败了customers_basket.
如果独立检查其他2个表,表products和products_description工作正常.
**由于原则,我决定@Jonathan Leffler应得的赏金.不仅是因为他的答案,也是因为他努力让我理解他给出的答案.所以请不要试图获得这笔赏金.如果我对SO保持封锁,我想对自己的最后一次行动充满信心**
看起来你的表组织有点奇怪,因为你通常不会期望找到它们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"
Run Code Online (Sandbox Code Playgroud)
但是,您更有可能需要在其他(尚未识别的)列上加入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
Run Code Online (Sandbox Code Playgroud)
这有点扭曲.
在我认为对这些可能代表什么的合理解释下,我希望客户(随着时间的推移)拥有多个篮子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
);
Run Code Online (Sandbox Code Playgroud)
这使产品描述表中的大部分产品描述成为可能.它为您提供了一个更简单的客户购物篮表 - 您可能会添加其他字段.客户篮子属性表也简单得多.
使用此结构,您可以将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"
Run Code Online (Sandbox Code Playgroud)
我没有研究过您的产品和产品描述表,看看它们如何协同工作.
| 归档时间: |
|
| 查看次数: |
561 次 |
| 最近记录: |