2015-11-26 37 views
1

表AMySQL的左JOIN B表GROUP BY A.id而是爲了通過B.id

id(UNIQUE) name 
    1  tomato 
    2  potato 

表B

id AID buy_date buy_money 
6 1 2015-01-01 100 
7 1 2015-02-02 200 

我想選擇與過濾名全A的記錄,與最新的buy_date和buy_money像這樣:

A.id A.name B.buy_date B.buy_money 
1 tomato 2015-02-02  200 
2 potato  NULL  NULL 

我該如何編寫SQL腳本?我曾嘗試過:

select A.id, A.name, MAX(B.buy_date) 
from A left join B on A.id = B.AID 
where A.name like '%to%' 
Group by A.id 

但是,這隻得到正確的buy_date,但沒有buy_money。這裏

+0

'選擇一個。*,x.buy_date,x.buy_money從連接BX ON b.aid = a.id JOIN(SELECT助劑,MAX(購買日期)max_buy_date來自組B BY助劑)Y Y上.aid = x.aid AND y.max_buy_date = x.buy_date;' – Strawberry

+0

@Strawberry有沒有簡單的方法沒有子查詢? – KKorange

+0

是的。但它慢... https://dev.mysql.com/doc/refman/5.7/en/example-maximum-column-group-row.html – Strawberry

回答

0

http://sqlfiddle.com/#!9/bee19b/1

SELECT A.id, A.name, t.* 
FROM A 
LEFT JOIN (
    SELECT B.* 
    FROM B 
    LEFT JOIN B b_ 
    ON b.AID = b_.AID 
    AND b.buy_date<b_.buy_date 
    WHERE b_.id IS NULL 
) t 
ON A.id = t.AID 
WHERE A.name LIKE '%to%' 
0

2種基本方法。

首先,如果購買日期對於AID是唯一的,那麼您可以使用子查詢獲得每個AID的最新buy_date,並將其與B表結合以獲取其餘細節。

一面是,如果有多個記錄具有相同交割日的AID你會得到多個記錄回到

SELECT A.id, A.name, B.buy_date, B.buy_money 
FROM A 
LEFT OUTER JOIN 
(
    SELECT AID, MAX(buy_date) AS max_buy_date 
    FROM B 
    GROUP BY AID 
) AS sub_B 
ON A.id = sub_B.AID 
LEFT OUTER JOIN B 
ON B.AID = sub_B.AID 
AND B.buy_date = sub_B.max_buy_date 
WHERE A.name like '%to%' 

第二種解決方案是使用GROUP_CONCAT讓所有的值返回,通過有序buy_date降序,然後使用SUBSTRING_INDEX將所有內容提交到第一個分隔符。 GROUP_CONCAT的默認分隔符是逗號,但如果您的值可能包含逗號,則可以輕鬆更改該分隔符。這是因爲它迫使日期和金錢字段轉換爲字符串。

SELECT A.id, 
     A.name, 
     SUBSTRING_INDEX(GROUP_CONCAT(B.buy_date ORDER BY B.buy_date DESC), ',', 1), 
     SUBSTRING_INDEX(GROUP_CONCAT(B.buy_money ORDER BY B.buy_date DESC), ',', 1) 
FROM A 
LEFT OUTER JOIN B 
ON B.AID = A.id 
WHERE A.name like '%to%' 
GROUP BY A.id, A.name