トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

9-23 nullのないグループを出力

SQLパズル

TestResultsテーブル
orderNo  step  compdate
-------  ----  --------
    100     1  20070110
    100     2  20070111
    100     3      null
    200     1      null
    200     2      null
    300     1  20070112
    400     1      null
    400     2  20070110
    500     1  20070111
    500     2  20070115

orderNoごとで、
compdateにnullが存在しない、orderNoを出力する

出力結果
orderNo
-------
    300
    500

SQLパズル(日本語版)のパズル19 [テストの結果] を参考にさせていただきました
SQLパズル 第2版のパズル20 [テスト結果] を参考にさせていただきました


データ作成スクリプト

create table TestResults as
select 100 as orderNo,1 as step,'20070110' as compdate from dual
union select 100,2,'20070111' from dual
union select 100,3,      null from dual
union select 200,1,      null from dual
union select 200,2,      null from dual
union select 300,1,'20070112' from dual
union select 400,1,      null from dual
union select 400,2,'20070110' from dual
union select 500,1,'20070111' from dual
union select 500,2,'20070115' from dual;


SQL

--■■■not existsを使う方法■■■
select distinct orderNo
  from TestResults a
 where not exists(select 1 from TestResults b
                   where b.orderNo = a.orderNo
                     and b.compdate is null)
order by orderNo;

--■■■グループ化する方法1■■■
select orderNo
  from TestResults
group by orderNo
having count(*) = count(compdate)
order by orderNo;

--■■■グループ化する方法2■■■
select orderNo
  from TestResults
group by orderNo
having min(nvl2(compdate,1,0)) = 1
order by orderNo;


解説

グループ化する方法1では、
count(compdate)が、nullを数えないことを使ってます

場合によっては、
nullif関数やcase式などと、組み合わせた使い方もできます

集合で考える ―― HAVING句の力:その2
Thinking in Aggregates(英語)