1

我有一个带有容器编号的表和一个带有时间戳的 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

有任何想法吗?

4

7 回答 7

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
于 2012-12-19T15:40:54.827 回答
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
于 2012-12-19T15:46:02.960 回答
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 是否支持这一点)。

于 2012-12-19T16:53:34.257 回答
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根据这些计算出实际计数。

于 2012-12-19T15:40:54.587 回答
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;
于 2012-12-19T15:41:00.347 回答
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;
于 2012-12-19T15:41:32.230 回答
0

count 函数默认不计算 null。您可以使用 nvl2 函数来操作查询,以帮助您仅计算空值。例子 :

select count(completed_on) as completed , 
       count(nvl2(completed_on,null,1)) as pending
from containers;
于 2012-12-20T09:59:36.780 回答