如何获得这些子查询的rif?
(所有表都有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
出于性能原因,我想摆脱这些子查询? 我怎样才能替换子查询?
提前致谢!
答案 0 :(得分:3)
根据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;
发送给出正确的结果
根据您的查询结果尝试以下查询
{{1}}
这里sql小提琴:
sql fiddle link
如果您想要其他结果,请发表评论。
答案 1 :(得分:0)
SELECT *
FROM Process AS p
LEFT JOIN (
SELECT ph.ProcessID, ph.HistoryID, h.Title AS HistoryTitle
FROM ProcessHistory AS ph
JOIN History AS h ON ph.HistoryID = h.ID
WHERE h.ID = 1
) AS phh ON p.ID = phh.ProcessID
ORDER BY p.ID DESC LIMIT 100
答案 2 :(得分:0)
由于实际的子查询,用于获取与每个“进程”相关的“最后”行,您既不能将其转换为JOIN,也不能将其用作单独的查询来设置会话变量。
答案 3 :(得分:0)
您仍然需要制作另一个选择来过滤掉剩余的流程历史记录,但您应该使用derived table而不是子查询,例如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所指出的那样,您的查询得到了一个按特定状态过滤的列表(最新的历史ID是1 - "所有打开的流程")"不会产生预期的效果。它只会返回历史ID为1的所有进程。请参阅此sqlfiddle。
相反,您希望使用派生表来获取这些最新的流程历史记录ID,将它们与流程连接,并过滤历史记录ID,例如sqlfiddle:
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,但在某些情况下,性能可以通过这种方式得到改善。