2016-08-08 23 views
3

我有兩個具有一對多關係的表。獲取數據,其中MAX(日期)<X

Table1 
ID name email 
Table2 
ID table1_ID date 

我需要從表1 where獲取所有數據:

MAX(date) from Table2 < "2016-01-01" 

這是行不通的。在where子句中Max被認爲是「無效的」。我做的是:

SELECT Table1.name, Table1.email, tmp.maxdate 
FROM Table1 
JOIN ( SELECT MAX(date) maxdate, table1_ID 
     FROM Table2 
     GROUP BY table1_ID) as tmp 
    ON tmp.table1_ID = table1.id 
WHERE tmp.maxdate < "2016-01-01" 
AND  (other conditions) 

所以這個工程。但我認爲表現會很糟糕 - explain顯示所有Table2正在被讀取,而這張表會增長很多。

任何想法,否則我該怎麼做,或者如何提高我目前的查詢性能?

+0

爲什麼你認爲表現糟透了? –

+1

有點奇怪,你會將tmp加入到table1中,而不是包括將tmp加入表2的中間步驟。另外,我會將WHERE子句放入子查詢中。除此之外,一個合適的索引,這個查詢應該是快速的。 – Strawberry

+1

由於'MAX(date)'是一個聚集,它不能放在'WHERE'中,而是屬於'HAVING'。無論如何,正如其他人指出的那樣,您可以簡單地使用'WHERE date>'2016-01-01'',而不是'HAVING MAX(date)>'2016-01-01''。 –

回答

2

嘗試:

SELECT Table1.name, Table1.email, tmp.maxdate 
FROM Table1 
INNER JOIN ( SELECT MAX(date) maxdate, table1_ID 
     FROM Table2 
     GROUP BY table1_ID 
     HAVING maxdate > "2016-01-01") as tmp 
    ON tmp.table1_ID = table1.id 
WHERE 
AND  (other conditions) 

之前,您剛剛從表2帶回大家,並與表1加入。這將淘汰所有那些沒有maxdate>「2016-01-01」的人,並通過Table1加入。

+0

這是一個很好的觀點,@Strawberry在評論中也指出了這一點,謝謝! –

1

首先,別以爲,測試它由你自己檢查它。

其次,你可以嘗試使用EXISTS()這可能是稍快監守你可以過濾表2,而不是使用GROUP BY條款:

SELECT * FROM Table1 t1 
WHERE EXISTS(SELECT 1 FROM Table2 t2 
      WHERE t2.date > "2016-01-01" 
       AND t1.id = t2.table1_id 
       AND <Other Conditions>) 

您還可以添加table2.date > "2016-01-01"你的子查詢中。

此外,考慮增加以下指標:

Table1(id,name,email) 
Table2(table1_id,date) 

注意,我會根據你所提供的查詢這些指標,如果有額外的條件,這個指標可能是不完整的。

+0

您好,感謝您的回答!當然,索引是正確設置的。你仍然有一個非常有趣的觀點,那就是在哪裏存在。我不認爲它真的適合其他強制性要求(按照maxdate排序,限制結果集),但我會盡量玩一會兒。 –

相關問題