2016-04-30 78 views
5

MySQL从3个表中选择。MySQL从3个表中选择不同的产品

我有这些5个表:

CREATE TABLE `category` (
    `c_id` int(6) NOT NULL AUTO_INCREMENT, 
    `name` varchar(40) NOT NULL, 
    PRIMARY KEY (c_id) 
); 

CREATE TABLE `product` (
    `p_id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(40) NOT NULL, 
    `brand` varchar(30) NOT NULL, 
    `image_path` varchar(100) DEFAULT NULL, 
    PRIMARY KEY (p_id) 
); 

CREATE TABLE `shop` (
    `s_id` int(6) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `country` varchar(30) NOT NULL, 
    `province` varchar(30) NOT NULL, 
    `city` varchar(30) NOT NULL, 
    `suburb` varchar(30) NOT NULL, 
    `street` varchar(40) DEFAULT NULL, 
    `streetNumber` varchar(40) DEFAULT NULL, 
    `postalCode` int(4) DEFAULT NULL, 
    PRIMARY KEY (s_id) 
) ; 

CREATE TABLE product_category (
p_id INT NOT NULL, 
c_id INT NOT NULL, 
PRIMARY KEY (p_id, c_id), 
FOREIGN KEY (p_id) REFERENCES Product(p_id) ON UPDATE CASCADE, 
FOREIGN KEY (c_id) REFERENCES Category(c_id) ON UPDATE CASCADE 
); 

CREATE TABLE product_shop (
p_id INT NOT NULL, 
s_id INT NOT NULL, 
PRIMARY KEY (p_id, s_id), 
FOREIGN KEY (p_id) REFERENCES product(p_id) ON UPDATE CASCADE, 
FOREIGN KEY (s_id) REFERENCES shop(s_id) ON UPDATE CASCADE 
); 

基本上,产品可以有很多类别。一个类别可以分配给许多产品。一家商店可以有很多产品。产品可以在许多商店。

我想选择其中category.c_id = 2,或category.c_id = 8和shop.s_id = 1个或shop.s_id = 2

我部分的方式有与此所有产品:

select * 
from product inner join product_category 
on product_category.p_id=product.p_id 
where (product_category.c_id=2) 
or (product_category.c_id=8) 

这得到所有有2个,也一个大类产品编号为8的类别编号的产品,但它得到了相同的产品两次,如果它既有category.c_id = 8,category.c_id = 2.

然后我试着让它获得独特的产品:

select DISTINCT(product.p_id) as product 
from product inner join product_category 
on product_category.p_id=product.p_id 
where (product_category.c_id=2) 
or (product_category.c_id=8) 

这是现在截然不同,但没有显示足够的产品或类别的信息。我想在每一行中显示尽可能多的信息。

而下一步是只获取那些在shop.s_id = 1个或shop.s_id = 2

谁能帮我那里还是更接近?谢谢!

+0

尝试'SELECT DISTINCT *'或'SELECT DISTINCT col1,col2 ...' –

回答

2

假设您想要列出所有产品信息。如果您不希望产品重复,则可以使用IN子句。现在

select p.* 
from product p 
where p.p_id in (select c.p_id from product_category c where c.c_id in (2,8)) 
    and p.p_id in (select s.p_id from product_shop s where s.s_id in (1,2)) 

,如果你想要的类别和店铺的产品涉及到所有产品数据和列表,然后你可以使用加入和一些非常方便的功能。

select p.p_id, p.`name`, p.brand, GROUP_CONCAT(DISTINCT c.c_id SEPARATOR ', ') as categories, GROUP_CONCAT(DISTINCT s.s_id SEPARATOR ', ') as shops 
from product p inner join product_category c on p.p_id = c.p_id 
       inner join product_shop s on p.p_id = s.p_id 
where c.c_id in (2,8) 
    and s.s_id in (1,2) 
group by p.p_id, p.`name`, p.brand 
+0

谢谢!出于某种原因,它显示在一个产品的结果行中,用于类别和商店: 2,8,8,2 1,2,1,2例如,它有一个产品的重复商店和类别。我已经在我的product_category表中发布了一张照片...我在那里做错了什么,这是否让它重复了单个产品的类别和商店? – BeniaminoBaggins

+0

发生这种情况是因为该产品在2个商店中存在,并且与2个类别相关:2 x 2 =产品出现4次。解决方案是在group_concat上添加独特的。看到我的答案编辑。 –