我在数据库中有两个表。 表客户端看起来像这样:
----------------------------
|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代表什么感到困惑,如果它仍然返回重复项,或者可能是我错过了什么。
任何有关的帮助都将不胜感激。
最佳,
阿赫桑
答案 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表中获取任何匹配的记录。