根据字段计数

时间:2012-12-19 15:37:34

标签: sql oracle

我有一个包含容器编号的表和一个带有时间戳的completed_on日期字段。它还有船只id和起重机id。我需要通过询问completed_on是否为空来计算已完成容器的数量并且未完成。

我写过类似的内容,但它不起作用。

select vessel,
  crane_no,
  count(container_no) tot_moves,
  case when completed_on is null then count(container_no) end as pending,
  case when completed_on is not null then count(container_no) end as completed,
min(completed_on) first_m,
max(completed_on) last_m
from
containers
group by vessel, crane_no, completed_on

有什么想法吗?

7 个答案:

答案 0 :(得分:2)

你非常接近...... case语句应该在你的聚合count函数中:

select 
  vessel,
  crane_no,
  count(container_no) tot_moves,
  count(case when completed_on is null then 1 end) as pending,
  count(case when completed_on is not null then 1 end) as completed,
  min(completed_on) first_m,
  max(completed_on) last_m
from
  containers
group by 
  vessel, 
  crane_no, 
  completed_on

答案 1 :(得分:2)

试试这个:

    select 
      vessel,
      crane_no,
      count(container_no) tot_moves,
      count(case when completed_on is null then 1 end) as pending,
      count(case when completed_on is not null then 1 end) as completed,
      min(completed_on) first_m,
      max(completed_on) last_m
    from containers group by  vessel, crane_no, completed_on

答案 2 :(得分:2)

还有另一种方法,不使用CASE。我不确定Oracle如何优化,但可能更快(您需要自己进行分析)。

select vessel,
       crane_no,
       count(container_no) tot_moves,
       count(*) - count(completed_on) as pending,
       count(completed_on) as completed,
       min(completed_on) first_m,
       max(completed_on) last_m
from containers
group by vessel, crane_no, completed_on

这很有效,因为几乎所有聚合(包括COUNT())都会忽略空值。您可以使用总行数与已完成行数的差异来获取待处理的行数。此外,count(completed_on) 缓存,并且不会运行两次(某些RDBMS允许在SELECT子句中重用列别名,但我不知道如果Oracle支持这个)。

答案 3 :(得分:1)

类似的东西:

select vessel,
    crane_no,
    count(container_no) tot_moves,
    sum(case when completed_on is null then 1 else 0 end) as pending,
    sum(case when completed_on is not null then 1 else 0 end) as completed,
    min(completed_on) first_m,
    max(completed_on) last_m
from containers
group by vessel, crane_no, completed_on;

case决定是否应计算每一行,sum根据这些计算实际计数。

答案 4 :(得分:1)

将count()放在案例周围。

select vessel,
  crane_no,
  count(container_no) tot_moves,
  count(case when completed_on is null then container_no end) as pending,
  count(case when completed_on is not null then container_no end) as completed,
min(completed_on) first_m,
max(completed_on) last_m
from
containers
group by vessel, crane_no;

答案 5 :(得分:1)

SELECT
  vessel,
  crane_no,
  COUNT(container_no)                                       AS "tot_moves",
  SUM(CASE WHEN completed_on IS NULL     THEN 1 ELSE 0 END) AS "pending",
  SUM(CASE WHEN completed_on IS NOT NULL THEN 1 ELSE 0 END) AS "completed",
  MIN(completed_on) first_m,
  MAX(completed_on) last_m
FROM containers
GROUP BY vessel, crane_no;

答案 6 :(得分:0)

默认情况下,count函数不会计数null。 您可以使用nvl2函数来操作查询,以帮助您只计算空值。 例如:

select count(completed_on) as completed , 
       count(nvl2(completed_on,null,1)) as pending
from containers;