2017-11-18 87 views
0

我一直在尝试两天,没有运气。SQL左连接:如何从tableB返回最新并由另一个字段分组

我有我的数据库中以下简化表:

客户:

| id | name  | 
| 1 | andrea | 
| 2 | marco | 
| 3 | giovanni | 

访问:

| id | name_id | date | 
| 1 | 1  | 5000 | 
| 2 | 1  | 4000 | 
| 3 | 2  | 1500 | 
| 4 | 2  | 3000 | 
| 5 | 2  | 1000 | 
| 6 | 3  | 6000 | 
| 7 | 3  | 2000 | 

我想所有的名字与他们的最后访问日期返回。

起初我

SELECT * FROM customers LEFT JOIN access ON customers.id = 
access.name_id 

只是尝试,但我得到了7行,而不是3预期。所以I understood I need to use GROUP BY statemet如下所示:

SELECT * FROM customers LEFT JOIN access ON customers.id = 
access.name_id GROUP BY customers.id 

据我所知,GROUP BY使用随机行联合收割机。事实上,我有几个测试无序的访问日期。

相反,我需要将每个客户ID与其对应的最新访问进行分组!如何做到这一点?

+0

我不确定我是否正确理解您希望在这里实现的目标,但我留下的印象可能会误解LEFT JOIN的工作原理。如果您拥有像MAX或MIN这样的聚合功能,则GROUP BY将起作用。你能更好地解释你期望看到的输出是什么? – Stefano

+0

@decadenza。 。 。 “SELECT *”与“GROUP BY”的使用是一个破碎的问题,它已经在最新版本的MySQL中得到了很好的解决。这不是做你想做的事的正确方法。 –

回答

1

您必须从访问表中获取最近的日期,并在name_id上​​使用group by,然后将此结果与客户表。以下是查询:

select c.id, c.name, a.last_access_date from customers c left join 
(select id, name_id, max(access_date) last_access_date from access group by name_id) a 
on c.id=a.name_id; 

这是在sqlfiddle上的DEMO。如果这个说法是正确的

SELECT a.*, c.* 
FROM customers c LEFT JOIN 
    access a 
    ON c.id = a.name_id AND 
     a.DATE = (SELECT MAX(a2.date) FROM access a2 WHERE a2.name_id = a.name_id); 

1

我认为这是你想达到什么样的:

SELECT c.id, c.name, max(a.date) last_access 
FROM customers c 
LEFT JOIN access a ON c.id = a.name_id 
GROUP BY c.id, c.name 

的LEFT JOIN将返回表客户的所有条目无论是否连接标准(c.id = a.name_id)满意。这意味着你可能会得到一些NULL条目。

例子:

只需在客户表中添加一个新行(ID:4,名称:曼努埃拉)。输出将有4行,最新的行将是(id:4,last_access:null)

1

我的ON子句中使用相关子查询做到这一点

我需要组每一位客户ID与其对应的最新的访问!如何做到这一点?

然后,你可以简单地做:

​​

你不需要customers表,因为:

  • 所有的客户都在access,所以left join是没有必要的。
  • 您不需要customers的列。
相关问题