SQLite3使用LEFT JOIN和UNION模拟RIGHT OUTER JOIN

sad*_*ave 8 sql sqlite union group-by full-outer-join

我有以下select语句,我需要从表tbTasks中对每个任务求和,并通过表tbProjects中的projectId对它们进行分组,以获得如下记录:

ProjectID = 1, ProjectName = 'My Project', TotalTime = 300 //<--sum of each task time
Run Code Online (Sandbox Code Playgroud)

查询如下所示:

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
Run Code Online (Sandbox Code Playgroud)

这工作并执行正常,但有一个问题,如果一个项目没有与之关联的任务,那么我根本没有得到任何记录(我想获得projectId,projectName和0或NULL的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
Run Code Online (Sandbox Code Playgroud)

只有这不起作用,我得到一个SQL语法错误.我究竟做错了什么?有没有更好的方法来实现我的目标?

voi*_*hos 14

即使SQLite 没有实现, 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
Run Code Online (Sandbox Code Playgroud)

NULLStotalTime为没有任何任务的项目,并调用COALESCE()一个替换为空0.

  • @sadmicrowave:对不起,我没有看到你的第二个问题.是的,有一种非常简单的方法可以返回0而不是NULL.看我编辑的答案. (2认同)

Mah*_*zad 5

版本 3.39.0开始,SQLite 支持右外连接和全外连接:

SELECT *
FROM t1 RIGHT JOIN t2
  ON t1.id = t2.id;
Run Code Online (Sandbox Code Playgroud)

感谢 Lukasz Szozda 的回答