[英]How to replace sub-query by joins?
如何獲得這些子查詢的內容?
(所有表的列Created和LastEdited作為時間戳)
table Process
- ID
- Title
table ProcessHistory
- ID
- ProcessID
- HistoryID
table History
- ID
- Title (new, open, closed etc.)
當我嘗試獲取帶有最后一個狀態標題的cols的進程列表時,我會這樣做:
SELECT DISTINCT Process.*, History.Title AS HistoryTitle, History.ID AS HistoryID
FROM `Process`
LEFT JOIN ProcessHistory AS ProcessHistory ON Process.ID=ProcessHistory.ProcessID
LEFT JOIN History AS History ON HistoryID=ProcessHistory.HistoryID
WHERE History.ID = (
SELECT HistoryID FROM ProcessHistory
WHERE ProcessID=Process.ID
ORDER BY ProcessHistory.ID DESC LIMIT 1
)
GROUP BY Process.ID
ORDER BY Process.ID DESC LIMIT 0, 100
當我嘗試獲取按特定狀態過濾的列表時(最新的HistoryID為1-“所有打開的進程”)
SELECT DISTINCT Process.*, History.Title AS HistoryTitle, History.ID AS HistoryID
FROM `Process`
LEFT JOIN ProcessHistory AS ProcessHistory ON Process.ID=ProcessHistory.ProcessID
LEFT JOIN History AS History ON HistoryID=ProcessHistory.HistoryID
WHERE History.ID=(
SELECT HistoryID FROM ProcessHistory
WHERE HistoryID =1
AND ProcessID=Process.ID ORDER BY ProcessHistory.ID DESC LIMIT 1
)
GROUP BY Process.ID
ORDER BY Process.ID DESC LIMIT 0, 100
出於性能原因,我想擺脫這些子查詢? 如何替換子查詢?
提前致謝 !
您發布的查詢未按照ORDER BY ProcessHistory.ID DESC LIMIT 1
提供正確的結果
根據查詢結果嘗試以下查詢
SELECT DISTINCT p.*, h.Title AS HistoryTitle,h.ID AS HistoryID
FROM
Process p JOIN ProcessHistory ph ON p.ID=ph.ProcessID and ph.HistoryID=1
JOIN History h ON h.ID=ph.HistoryID
GROUP BY p.ID
ORDER BY p.ID DESC LIMIT 0, 100;
這里的SQL小提琴:
sql小提琴鏈接
如果您想要其他結果,請發表評論。
由於實際的子查詢用於獲取與每個“進程”相關的“最后”行,因此您既不能將其轉換為JOIN,也不能將其用作設置會話變量的單獨查詢。
您仍然需要進行另一個選擇以過濾掉其余的過程歷史記錄,但是您應該使用派生表而不是子查詢,例如sqlfiddle :
SELECT Process.*, History.Title AS HistoryTitle
FROM Process
JOIN (
SELECT ProcessID, max(HistoryID) as HistoryID
FROM ProcessHistory
GROUP BY ProcessID
) PH ON PH.ProcessID = Process.ID
JOIN History ON History.ID = PH.HistoryID
ORDER BY Process.ID DESC LIMIT 0, 100
正如Himanshu Patel指出的那樣,您的查詢“獲取按特定狀態過濾的列表(最新的HistoryID為1-“所有打開的進程”)將無法產生預期的效果。 它只會返回所有HistoryID為1的進程。請參見此sqlfiddle 。
相反,您希望使用派生表來獲取這些最新的進程歷史記錄ID,將它們與進程一起加入,並過濾諸如sqlfiddle這樣的歷史記錄ID:
SELECT DISTINCT Process.*, History.Title AS HistoryTitle
FROM Process
JOIN (
SELECT ProcessID, max(HistoryID) as HistoryID
FROM ProcessHistory
GROUP BY ProcessID
) PH ON PH.ProcessID = Process.ID
JOIN History ON History.ID = PH.HistoryID
WHERE PH.HistoryID = 1
ORDER BY Process.ID DESC LIMIT 0, 100
一種替代方法是創建一個視圖,該視圖將ProcessHistory表篩選為每個進程的最新歷史記錄,然后加入該視圖。 YMMV,但在某些情況下,可以通過這種方式提高性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.