- PR -

グループ化&すべてNULLのデータを取得するSQL文

投稿者投稿内容
NGO
常連さん
会議室デビュー日: 2005/06/15
投稿数: 29
投稿日時: 2006-09-19 12:03
いつもお世話になっております。

Oracle10gを使用しております。

グループ化した状態で、とあるフィールドの値がすべてNULLのデータだけを抽出したいと思っているのですが、思うようなSQL文を作成することができません。


[テーブルデータ]
NO|SEQ|SUB_SEQ|DATE
A1|001|01 |200601
A1|001|02 |NULL
A1|002|01 |NULL
B1|001|01 |200601
B1|001|02 |NULL
B2|001|01 |NULL
B2|001|02 |NULL

というデータの状態で
・NOの状態でグループ化
・グループ化した状態で、DATEの値がすべてNULL
というデータのNOを取得したいと思います。
(結果的に B2 という値が取得できればOK)

SELECT NO
FROM D_HACCYUU
WHERE DATE IS NULL
GROUP BY NO

だと、DATAがNULLの行が抽出されてしまいます。
(B2だけではなく、A1やB1も抽出されてしまう)

HAVING DATE IS NULL などと追加してみたものの、GROUP BYの箇所にDATEを追記してしまうと、DATEでグループ化されてしまうため、やはり「すべてNULL」という状態のデータを抽出できません。


SQL文そのものですと非常にありがたいのですが、こういった関数(?)や手法を用いれば取得できるというヒントだけでもかなり助かります。

なにとぞよろしくお願いいたします。
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2006-09-19 12:12
DATE列の型が不明なので、TO_CHARなどを
掛けないといけないかもしれませんが、
その辺は適当に改造してください。

■DATEが文字列だと仮定しております。
■実機で試してません。エラーがあったら申し訳ない

DATEの実データには999999はないでしょうから(恐らく)
select INLINE.NO
FROM
(
select no,NVL(DATE,'999999') mygroup FROM testtable
GROUP BY NVL(DATE,'999999')
INLINE
WHERE INLINE.mygroup = '999999'

で取れると思うのですが、如何でしょう(試してない)
platini
大ベテラン
会議室デビュー日: 2002/12/03
投稿数: 193
投稿日時: 2006-09-19 12:13
すいません。投稿したSQLではNGです。
条件を満足してません。考え直します。
Ahf
大ベテラン
会議室デビュー日: 2006/08/16
投稿数: 172
投稿日時: 2006-09-19 12:20
グループ化の対象が「NO」だけ、というところが少々気にかかりますが、
提示例より、A1はダメでB2がOKということですと、
NOでグルーピングした際のそれぞれの件数

SELECT NO, COUNT(*) FROM D_HACCYUU GROUP BY NO

を元にcount(*)の結果が1であったNOのデータをWHERE条件に加え
SELECTで抽出、というやり方ではどうでしょうか?

#グルーピングした結果はA1が2件、B1が2件、B2が1件だと思いますが
#合ってますか?
うにくま
ベテラン
会議室デビュー日: 2005/11/05
投稿数: 82
投稿日時: 2006-09-19 12:33
純粋にNO列が同一の件数(条件未設定)と、DATE列がNULLの場合の件数を比較して
件数が一致する場合がすべてNULLという判断になると思います。

動作確認はしてませんが、以下のようなSQLです。
コード:
SELECT
        A.NO
FROM    (
        SELECT
                NO,
                COUNT(*)    AS RECORD_COUNT
        FROM    D_HACCYUU
        GROUP BY
                NO
        )    A
        INNER JOIN
        (
        SELECT
                NO,
                COUNT(*)    AS RECORD_COUNT
        FROM    D_HACCYUU
        WHERE   DATE        IS NULL
        GROUP BY
                NO
        )    B
        ON  A.NO            =  B.NO
        AND A.RECORD_COUNT  =  B.RECORD_COUNT

choir
会議室デビュー日: 2006/07/31
投稿数: 15
お住まい・勤務地: 東京都
投稿日時: 2006-09-19 12:45
SELECT NO
FROM [TABLE]
GROUP BY NO
HAVING (COUNT(DATE) = 0) ← NULLはCOUNTの対象にならないので。

>HAVING DATE IS NULL などと追加してみたものの
HAVING句の中で、Min、Max、Count等の集合関数が扱えることって割と忘れやすいんですよね。
自分も良く忘れています

[ メッセージ編集済み 編集者: choir 編集日時 2006-09-19 12:53 ]
NGO
常連さん
会議室デビュー日: 2005/06/15
投稿数: 29
投稿日時: 2006-09-19 13:29
さっそくのご返答、ありがとうございます。
結論から申しますと、うにくま様よりご提供いただいたSQL文で、望んでいた結果を得ることができました。
このSQL文を元に、また再考せねばならないのですが、質問自体はこれで締めさせていただきます。


>>platini様
何度も考慮を重ねたSQL文を投稿していただき、ありがとうございます。
私自身、SQLについては勉強が足らない部分が多々ありますため、NGとはいえ、このSQL文なども解析して、参考にさせていただきます。

>>Ahf様
本来はSEQ,SUB_SEQもいれて、データの一意化を図っているのですが、今回は
「NOごとの単位で判定する」
ということであるため、グループ化の対象をNOだけにいたしました。

>>うにくま様
SQL文までご掲示していただき、まことにありがとうございます。
こちらが望んでいた形でのデータ抽出をすることができました。
SQLを使い始めてからまだ日も浅いため、満足な知識もないままスタートしていたのですが、
「このような方法があるのか」
と目から鱗でございました。
さっそく使わせていただきます。
ありがとうございました。

>>choir様
NULLがCOUNTの対象にならないということなのですね?
今後のSQLを扱う際に参考にさせていただきます。


ご返答いただきました皆様、大変勉強になりました。
まことにありがとうございました。
eternia
常連さん
会議室デビュー日: 2006/02/23
投稿数: 42
投稿日時: 2006-09-19 13:34
choirさんとかぶってしまっている感じですが……

SELECT NO
FROM D_HACCYUU
GROUP BY NO
HAVING MAX(DATE) IS NULL

でいけませんか?

#残念 間に合わなかったっぽいorz

[ メッセージ編集済み 編集者: eternia 編集日時 2006-09-19 13:35 ]

スキルアップ/キャリアアップ(JOB@IT)