mysql在JOIN上返回重复项

时间:2013-07-12 19:44:33

标签: mysql join

我在数据库中有两个表。 表客户端看起来像这样:

----------------------------
|id | name | age | gender  |
|---------------------------
|1  | CL1  | 22  |  M      |
|2  | CL2  | 23  |  M      |
|3  | CL3  | 24  |  M      |
|4  | CL4  | 25  |  F      |
|5  | CL5  | 26  |  NA     |
----------------------------

现在我有另一个与此客户端表相关的表,请注意上表中的“id”不是AUTO_INCREMENT并且是UNIQUE。

第二个表是“images”,其中包含客户的投资组合图像,如下所示:

 ------------------------------
|id | client_id | url         |
|------------------------------
|1  | 1         | img1_1.jpg  | 
|2  | 1         | img1_2.jpg  | 
|3  | 1         | img1_3.jpg  | 
|4  | 2         | img2_1.jpg  | 
|5  | 2         | img2_2.jpg  |
-------------------------------

我基本上实现的是,我想从客户端表中提取所有结果,包括名称年龄性别等,以及图像表中的第一个和一个结果,这意味着,如果我查询它将必须向我显示如果我在客户端表中查询CL1,则来自images表的imag1_1.jpg。 为此,我正在做这样的事情:

SELECT DISTINCT c.* , i.* FROM clients c LEFT JOIN images i ON i.client_id = c.id

此查询返回结果,但结果更重复。我没有得到,或者我对DISTINCT代表什么感到困惑,如果它仍然返回重复项,或者可能是我错过了什么。

任何有关的帮助都将不胜感激。

最佳,

阿赫桑

3 个答案:

答案 0 :(得分:2)

这是使用相关子查询的一种方法:

SELECT c.*
     , ( SELECT i.url 
           FROM images i 
          WHERE i.client_id = c.id
          ORDER BY i.id
          LIMIT 1
       ) AS url 
  FROM clients c 

你真的不需要从images表中提取client_id,你已经知道它的价值了。如果需要从images表中返回id值,则需要在选择列表中添加另一个相关子查询

     , ( SELECT i.id
           FROM images i 
          WHERE i.client_id = c.id
          ORDER BY i.id
          LIMIT 1
       ) AS images_id

这种方法在大型集合上可能会变得昂贵,但对于从客户端返回的有限行数,它会合理地执行。

更通用的查询形式为:

SELECT c.*
     , i.*
  FROM clients c
  LEFT
  JOIN ( SELECT m.client_id, MIN(m.id) as images_id
           FROM images m
          GROUP BY m.client_id
       ) n
  LEFT
  JOIN images i
    ON i.id = n.images_id

别名为n的内联视图将从images表中为每个client_id获取单个id值,然后我们可以使用该id值连接回images表,以检索整行。

此表单的性能可能更好,但对于大型集,将内嵌视图显式化为n可能需要一些时间。如果在外部查询的client.id表上有谓词,那么为了获得更好的性能,也可以在内联视图中的m.client_id上重复该谓词,以限制行数。

答案 1 :(得分:1)

假设“ first ”表示最小images.id的记录,则表示您位于groupwise minimum之后:

SELECT * FROM images NATURAL JOIN (
  SELECT   client_id, MIN(id) id
  FROM     images
  GROUP BY client_id
) t JOIN clients ON clients.id = images.client_id

答案 2 :(得分:1)

SELECT DISTINCT ROW 为基础运作。它会检查一行中与所有其他行相关的所有值。如果即使一个值不同,那么该行也不是重复的,并且将输出整个事物。如果您想强制单个FIELD不同,那么您应该GROUP BY该字段。

由于您正在进行左连接,因此您将从clients表中获取所有记录,并从images表中获取任何匹配的记录。