1

コンテナ番号を含むテーブルと、タイムスタンプ付きの completed_on 日付フィールドがあります。また、船舶 ID とクレーン ID も含まれています。completed_on が null かどうかを確認して、完了したコンテナーと完了していないコンテナーの数をカウントする必要があります。

このようなことを書いていますが、うまくいきません。

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

を使用しないで、これを行う別の方法があります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()ほとんどすべての集計 ( を含む) が null を無視するため、これは機能します。行の総数と完了した行の数の差を使用して、保留中の移動を取得できます。また、キャッシュcount(completed_on) する必要があり、2 回実行されることはありません (一部の RDBMS では、句で列エイリアスを再利用できますがSELECT、Oracle がこれをサポートしているかどうかはわかりません)。

于 2012-12-19T16:53:34.257 に答える
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 に答える
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 関数を使用してクエリを操作すると、null のみをカウントできます。例 :

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