1

我在数据库中有两个表。表客户端如下所示:

----------------------------
|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 并且是唯一的。

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

 ------------------------------
|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  |
-------------------------------

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

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

此查询返回我的结果,但结果是更多重复。如果它仍然返回重复项,我没有得到或者我对 DISTINCT 所代表的含义感到困惑,或者我可能遗漏了一些东西。

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

最好的,

阿山

4

3 回答 3

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 上重复,以限制行数。

于 2013-07-12T19:56:44.880 回答
1

假设“第一个”是指具有最小值的记录images.id,那么您在分组最小值之后:

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
于 2013-07-12T19:54:59.023 回答
1

SELECT DISTINCTROW为基础运行。它检查一行中的所有值与所有其他行。如果甚至一个值不同,则该行不是重复的,并且将输出整个内容。如果您想强制单个 FIELD 是不同的,那么您应该GROUP BY改为该字段。

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

于 2013-07-12T19:55:38.983 回答