我有以下选择语句,我需要对表 tbTasks 中的每个任务求和,并按表 tbProjects 中的 projectId 对它们进行分组,以便获得这样的记录:
ProjectID = 1, ProjectName = 'My Project', TotalTime = 300 //<--sum of each task time
查询看起来像这样:
SELECT tbTasks.projectId,
SUM(tbTasks.taskTime) AS totalTime,
tbProjects.projectName
FROM tbTasks
INNER JOIN tbProjects ON tbTasks.projectId = tbProjects.projectId
GROUP BY tbTasks.projectId
ORDER BY tbProjects.created DESC
这工作和执行都很好,但有一个问题,如果一个项目没有与之关联的任务,那么我根本不会得到任何记录(我想在其中获取 projectId、projectName 和 0 或 NULL for totalTime)。因此,为了正确加入表 tbProjects,SQLite3 迫使我以一种迂回的方式进行。
SELECT tbTasks.projectId,
SUM(tbTasks.taskTime) AS totalTime,
tbProjects.projectName
FROM tbTasks LEFT OUTER JOIN tbProjects
ON tbTasks.projectId = tbProjects.projectId
GROUP BY tbTasks.projectId
UNION
SELECT tbProjects.projectId,
SUM(tbTasks.taskTime) AS totalTime,
tbProjects.projectName
FROM tbProjects LEFT OUTER JOIN tbTasks
ON tbProjects.projectId = tbTasks.projectId
GROUP BY tbTasks.projectId
ORDER BY tbProjects.created DESC
只有这个不起作用,我得到一个 SQL 语法错误。我究竟做错了什么?有没有更好的方法来实现我的目标?
最佳答案
尽管 SQLite hasn't implemented RIGHT OUTER
或 FULL OUTER
,它确实有LEFT OUTER JOIN
,它应该可以满足您的需求。只需将 tbProjects
放在左侧即可。
SELECT tbProjects.projectId,
COALESCE(SUM(tbTasks.taskTime), 0) AS totalTime,
tbProjects.projectName
FROM tbProjects
LEFT OUTER JOIN tbTasks ON tbProjects.projectId = tbTasks.projectId
GROUP BY tbProjects.projectId
ORDER BY tbProjects.created DESC
对于没有任何任务的项目,您在 totalTime
中得到 NULLS
,并且调用 COALESCE()
用 0
替换 null。
关于SQLite3 使用 LEFT JOIN 和 UNION 模拟 RIGHT OUTER JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9147025/