获取内部联接中特定实例的计数?

时间:2014-12-08 17:55:33

标签: mysql sql join count

我有三个表:用户,列表和任务。

列表将user_id作为外键。 tasks表将list_id作为外键,将user_id作为字段。

我使用以下SQL语句来显示用户列表和已完成任务的数量:

SELECT
    list.list_id,
    list_name,
    list_time_created,
    COUNT( task.task_id ) AS numberofTasks,
    COUNT( CASE WHEN task.task_completed=1 THEN 1 END) AS numberofCompletedTasks
FROM list
INNER JOIN task
    ON list.user_id = ':user_id' AND list.list_id = task.list_id
GROUP BY list_name

全桌设计如下:

列表

  • LIST_ID
  • LIST_NAME
  • user_id FK

任务

  • TASK_ID
  • TASK_NAME
  • task_completed
  • USER_ID
  • list_id FK

它不起作用。如何修改此语句以获取用户的所有列表(即使列表不包含任务)并获取任务数量(总计和已完成)(如果有)?

2 个答案:

答案 0 :(得分:1)

您的部分问题是您只检查列表中的user_id。您还需要确保在任务表中获得正确的user_id。一种方法是在该条件下连接表,然后在where子句中检查特定用户。

其次,如果您想查看列表,无论它是否有任务,您都应该使用外部联接。如果您这样做,我建议您修改聚合函数以处理空值。尝试这样的事情:

SELECT 
  l.list_id, l.list_name, l.list_time_created, 
  COUNT(CASE WHEN t.task_id IS NULL THEN 0 ELSE 1 END) AS numberOfTasks,
  SUM(CASE WHEN t.task_completed IS NULL THEN 0 ELSE t.task_completed END) AS numberOfCompletedTasks
FROM list l
LEFT JOIN task t ON l.list_id = t.list_id AND l.user_id = t.user_id
WHERE l.user_id = 1
GROUP BY l.list_id;

这将选择您的列,计算task_id的所有非空实例,每个list_id的task_completed为1的所有实例。这将显示所有list_ids,因此如果它没有任务,我们将看到计数为0.由于您要查询特定用户,因此无需在此处执行user_id的其他分组。

由于task_completed为0或1,因此使用SUM聚合函数将有效地为您提供已完成任务的计数。我使用了一个检查,但是对于null实例,它与0相加。

这对我来说是SQL Fiddle,请告诉我这是否会给你带来麻烦。

修改

如果我可以对您的表格设计发表评论,我建议您从其中一个表格中删除user_id。两者都没有必要。假设您从任务表中删除user_id。我可以从task->列表中获取user_id。如果我同时使用它们,它们可能会不一致。但是,这只是一个评论。我不知道你的整个情况,改变你的设计可能不太可能,或者你有理由这样做。

答案 1 :(得分:-1)

使用left join,即使任务中没有可用记录,也会显示您的列表。