2017-11-18 151 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的列。
相關問題