SQLite3 Имитация правого соединения с левыми соединениями и объединением - PullRequest
8 голосов
/ 05 февраля 2012

У меня есть следующий оператор выбора, в котором мне нужно суммировать каждую задачу из таблицы tbTasks и группировать их по projectId из таблицы tbProjects, чтобы получить такую ​​запись:

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 Ответ

14 голосов
/ 05 февраля 2012

Несмотря на то, что 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

Вы получаете NULLS в totalTime для проектов, у которых нет задач, а вызов COALESCE() заменяет ноль на 0.

...