SQL查询即使在一个表中count为0也能获取记录

时间:2012-05-16 07:48:48

标签: sql

select id, name, 'First Category' as category, count(id) as totalCalls
from missed_call
where name = 'whatever1'
group by name, category
UNION
select id, name, 'Second Category' as category, count(id) as totalCalls
from missed_call
where name = 'whatever2'
group by name, category
order by name ASC, totalCalls DESC

上一个查询不会检索 totalCalls 为0的记录。

那么,如何获取这些记录并将 totalCalls 显示为0?

更新:我尝试更改count(id) as totalCalls IFNULL(count(id), 0) as totalCalls,但无法解决问题。也许,因为count(id)实际上不是null,它就不存在了。

3 个答案:

答案 0 :(得分:3)

如果您不愿意扩展数据库架构,可以随时假装有一个表:

select surrogateTable.name, 
       surrogateTable.Category, 
       count(id) as totalCalls
from 
(
  select 'whatever1' Name,
         'First Category' Category
  union all
  select 'whatever2',
         'Second Category'
) surrogateTable
left join missed_call
  on surrogateTable.Name = missed_call.Name
group by surrogateTable.name, surrogateTable.category

我在select中删除了id,因为你不应该选择你没有分组的东西 - 这可能是MySql。

Check this on Sql Fiddle

答案 1 :(得分:1)

您的问题是,您只会查看未接来电而非类别,因此您无法注意到没有相应未接来电的类别。

以下是将要执行此操作的框架,假设您将其调整为类别表的实际结构。

SELECT ...
FROM Category cat
    LEFT JOIN missed_call call ON call.category = category.id
WHERE (call.name = 'whatever1' OR call.category IS NULL)
GROUP BY call.name, call.category
...

请特别注意call.category IS NULL。据说该列不可为空;所以这确实会检查Category行而没有任何相应的调用,这是外连接的工件。

答案 2 :(得分:0)

您应该定义一个名为category的表,以包含可能的所有类别名称的完整列表,即使那些没有分配给它们的呼叫(即零)。

create table category
(
    id  numeric(10,0) NOT NULL,
    name    varchar(10) NULL
)

然后,您可以从此表中查询完整的类别列表,并根据上面的内容左键加入结果。

然后,您可以修改missed_call以对新的category表使用外键,以提高效率和更好的架构设计

create table missed_call
(
    id  numeric(10,0) NOT NULL,
    first_category_id numeric(10,0) NULL,
    second_category_id numeric(10,0) NULL,
    name  varchar(12)
)