[英]How to replace sub-query by joins?
How can i get rif of theses subqueries ? 如何获得这些子查询的内容?
(all tables have columns Created and LastEdited as timestamps) (所有表的列Created和LastEdited作为时间戳)
table Process
- ID
- Title
table ProcessHistory
- ID
- ProcessID
- HistoryID
table History
- ID
- Title (new, open, closed etc.)
When i try to get a list of processes with cols of the last status title i do: 当我尝试获取带有最后一个状态标题的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
When i try to get a list filtered by a specific status (Where the latest HistoryID is 1 - "all open Processes") 当我尝试获取按特定状态过滤的列表时(最新的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
For performance reasons i want to get rid of theses subqueries? 出于性能原因,我想摆脱这些子查询? How can i replace the subquery? 如何替换子查询?
Thanks in advance ! 提前致谢 !
Query you posted not give proper result as per ORDER BY ProcessHistory.ID DESC LIMIT 1
您发布的查询未按照ORDER BY ProcessHistory.ID DESC LIMIT 1
提供正确的结果
Try below query as per result of your query 根据查询结果尝试以下查询
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;
Here the sql fiddle: 这里的SQL小提琴:
sql fiddle link sql小提琴链接
If you want other result then comment. 如果您想要其他结果,请发表评论。
由于实际的子查询用于获取与每个“进程”相关的“最后”行,因此您既不能将其转换为JOIN,也不能将其用作设置会话变量的单独查询。
You'll still need to make another select to filter out the rest of the process history, but you should use a derived table instead of a subquery, like this sqlfiddle : 您仍然需要进行另一个选择以过滤掉其余的过程历史记录,但是您应该使用派生表而不是子查询,例如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
As Himanshu Patel pointed out, your query to "get a list filtered by a specific status (Where the latest HistoryID is 1 - "all open Processes")" will not produce the desired effect. 正如Himanshu Patel指出的那样,您的查询“获取按特定状态过滤的列表(最新的HistoryID为1-“所有打开的进程”)将无法产生预期的效果。 It will simply return all processes that have a HistoryID of 1. See this sqlfiddle . 它只会返回所有HistoryID为1的进程。请参见此sqlfiddle 。
Instead, you want to use a derived table to get those latest process history ids, join them with the processes, and filter on the history ids like this 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
An alternative approach would be to create a view that filters the ProcessHistory table to the latest history per process and join on that. 一种替代方法是创建一个视图,该视图将ProcessHistory表筛选为每个进程的最新历史记录,然后加入该视图。 YMMV, but in some cases, performance can be improved that way. YMMV,但在某些情况下,可以通过这种方式提高性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.