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

Posted

技术标签:

【中文标题】SQLite3 使用 LEFT JOIN 和 UNION 模拟 RIGHT OUTER JOIN【英文标题】:SQLite3 Simulate RIGHT OUTER JOIN with LEFT JOINs and UNION 【发布时间】:2012-02-27 03:43:55 【问题描述】:

我有以下选择语句,我需要对表 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 的 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 语法错误。我究竟做错了什么?有没有更好的方法来实现我的目标?

【问题讨论】:

【参考方案1】:

即使 SQLite hasn't implemented RIGHT OUTERFULL 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() 的调用会将 null 替换为 0

【讨论】:

是否有 eval 函数返回 0 而不是 NULL? 仅供参考,解决了这个问题。我只是在遍历查询结果时进行了变量检查,如果为 null,则变量设置为 0。感谢您的帮助,我显然想多了。 @sadmicrowave:抱歉,我没有看到你的第二个问题。是的,有一种非常简单的方法可以返回 0 而不是 NULL。请参阅我编辑的答案。

以上是关于SQLite3 使用 LEFT JOIN 和 UNION 模拟 RIGHT OUTER JOIN的主要内容,如果未能解决你的问题,请参考以下文章

关于SQL 查询效率问题 left join 改成 inner join union

使用 LEFT JOIN 和 INNER JOIN 插入

Hibernate 中 LEFT JOIN 和 LEFT JOIN FETCH 的区别?

深入Oracle的left join中on和where的区别详解

关于VF中select left(right) join的准确用法

在 Redshift 上混合使用 CROSS JOIN 和 LEFT JOIN