【问题标题】:Joining two tables in a SELECT query is not working [closed]在 SELECT 查询中加入两个表不起作用[关闭]
【发布时间】:2012-01-01 20:04:38
【问题描述】:

我经营一个购物车,其中的产品可以有更多选择。例如,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_attributescustomers_basket 之间失败了。

productsproducts_description 工作正常,如果将它们与其他 2 个表单独检查。

** 由于原则,我认为@Jonathan Leffler 应该得到赏金。不仅是为了他的回答,也是为了他努力让我理解他给出的答案。所以请不要试图赚取这个赏金。如果我一直被阻止,我想对我的最后一个行动充满信心**

【问题讨论】:

  • 你为什么不先解释一下你想要完成什么?也可能是架构的相关部分。
  • 我不同意你的观点,很难说你想做什么。无论如何,祝你好运。
  • 建议您发布示例数据和所需结果。
  • 这就像你在 Stack Overflow 上回答了所有最糟糕的问题,在这些问题上编译了我所有的 cmets,然后做了与我要求那些原始海报做的完全相反的事情,并形成了这个问题作为结果.
  • @whitehat:仅仅因为you don't think you have a need for the question and answer anymore 并不意味着您应该清除所有内容并使所有答案无效。我们在 Stack Overflow 上认为这非常很糟糕,社区倾向于标记这种行为,这可能会促使管理员采取进一步行动。

标签: sql sqlite count


【解决方案1】:

您的表组织似乎有点奇怪,因为您通常不会期望找到包含products_id 列的Customers_BasketCustomers_Basket_Attributes。但是,从表面上看,并使用现代 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"

我没有研究过您的产品和产品描述表,以了解它们如何协同工作。

【讨论】:

  • 我在此清除了 cmets,因为您回复的 cmets 已被删除。看起来你正在和自己进行一次非常奇怪但有趣的对话。
  • 您对这个问题的耐心让我印象深刻。看起来你最终到达了那里。
【解决方案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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-15
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    相关资源
    最近更新 更多