2012-05-19 29 views
0

我有两个表:加入两个MySQL表,但附加条件?

产品:

+-------------------------------------------------+ 
| id | name | category  | price | 
+-------------------------------------- ----------+ 
| 1 | item1 |  1   | 0.99 | 
| 2 | item2 |  2   | 1.99 | 
| 3 | item3 |  3   | 2.95 | 
| 4 | item4 |  4   | 2.50 | 
+-------------------------------------------------+ 

图片:

+--------------------------------------------------+ 
| id | file_name | p_id | priority | 
+-------------------------------------- -----------+ 
| 1 |  image1  |  1 |  0  | 
| 2 |  image2  |  1 |  1  | 
| 3 |  image3  |  2 |  2  | 
| 4 |  image4  |  3 |  2  | 
| 5 |  image5  |  3 |  3  | 
| 11 |  image6  |  3 |  5  | 
| 16 |  image7  |  4 |  1  | 
| 19 |  image8  |  4 |  7  | 
+--------------------------------------------------+ 

我需要把所有的产品信息,以及图像的文件名的产品。请注意,产品可以有多个图像;我想要最低优先。另外,我只希望获得某个类别产品的结果。

所以,说我需要在类{1,2,3}产品信息,然后在查询运行后的结果应该返回:

+-----------------------------------------------------------------+ 
| id | name | category  | price | file_name | 
+-------------------------------------- ----------+---------------+ 
| 1 | item1 |  1   | 0.99 |  image1 | 
| 2 | item2 |  2   | 1.99 |  image3 | 
| 3 | item3 |  3   | 2.95 |  image4 | 
+-------------------------------------------------+---------------+ 

我曾尝试写了几个不同的连接语句,但他们都没有工作;这并不奇怪,因为在SQL方面,我是一个总新手。

任何帮助将不胜感激!

回答

2

这就是答案:

select a.id, a.name, a.category, a.price, b.filename as file_name 
from products a left join (
    select i.p_id, i.filename from (select id, min(priority) as min_p 
    from images group by p_id) q 
    left join images i on q.id = i.id 
) b on a.id = b.p_id 
where a.category in (1, 2, 3); 

说明:

首先,你需要得到一组,其中对于每个具有最低优先级的产品,从此查询中获得:

select id, min(priority) as min_p from images group by p_id; 

结果将是:

+----+----------+ 
| id | lowest_p | 
+----+----------+ 
| 1 |  0 | 
| 2 |  2 | 
| 3 |  2 | 
| 4 |  1 | 
+----+----------+ 
4 rows in set (0.00 sec) 

下一步会得到一个外连接,在这种情况下,我会选择(任意根据我的偏好),左联接:

select i.p_id, i.filename from (select id, min(priority) as min_p 
from images group by p_id) q left join images i on q.id = i.id; 

此查询产生你想要什么简称:

+------+----------+ 
| p_id | filename | 
+------+----------+ 
| 1 | image1 | 
| 2 | image3 | 
| 3 | image4 | 
| 4 | image7 | 
+------+----------+ 
4 rows in set (0.00 sec) 

现在你只需要装饰这一点,再次使用左连接:

select a.id, a.name, a.category, a.price, b.filename as file_name 
from products a left join (
    select i.p_id, i.filename from (select id, min(priority) as min_p 
    from images group by p_id) q 
    left join images i on q.id = i.id 
) b on a.id = b.p_id 
where a.category in (1, 2, 3); 

,你会得到你想要的东西:

+------+-------+----------+-------+-----------+ 
| id | name | category | price | file_name | 
+------+-------+----------+-------+-----------+ 
| 1 | item1 |  1 | 0.99 | image1 | 
| 2 | item2 |  2 | 1.99 | image3 | 
| 3 | item3 |  3 | 2.95 | image4 | 
+------+-------+----------+-------+-----------+ 
3 rows in set (0.00 sec) 

你也可以把产品在左边的右边加入,这取决于你所期望的时候有没有图像产品可用。上面的查询将显示上面的视图,其中file_name字段为“null”。

另一方面,如果您将产品放在左侧连接的右侧,它将不会显示任何内容。

4

我将添加一步一步的教程,首先获取联合权利, 然后添加一些条件来过滤类别,最后,分组 和使用具有子选择的having子句。您需要在代码中使用最后选择的 。我也在一个mysql实例上测试了它,它工作。 如果您需要其他复杂的东西,我正在使用group。有一个例子是很好的。 语法ANSII SQL,就应该对所有数据库的工作不只是在mysql

-- get everything by joining 
select p.*, i.file_name 
from products p 
join image i on (p.id = i.p_id) 



/* get everything by joining 
* + filter by category 
*/ 
select p.*, i.file_name 
from products p 
join image i on (p.id = i.p_id) 
where p.category in (1,2,3) 


/* get everything by joining 
* + filter by category 
* + image is the one with the lowest priority 
* note: selecting the priority is not necessary 
* but it's good for demonstration purposes 
*/ 
select p.*, i.file_name, i.priority 
from products p 
join image i on (p.id = i.p_id) 
where p.category in (1,2,3) 
group by p.id 
having i.priority = (select min(priority) from image where p_id = p.id) 
0

大厦sarwar026的答案...

SELECT p.id, name, priority, price, file_name 
FROM Products p, Images i 
WHERE p.id = i.p_id 
    AND i.priority = (SELECT MIN(priority) FROM Images ii WHERE ii.p_id = p.id) 
    AND p.category IN (1,2,3) 

(与你的表的副本MySQL数据库上测试)