- PR -

検索結果0件の場合,カウント

投稿者投稿内容
ひろ
ベテラン
会議室デビュー日: 2003/12/26
投稿数: 97
投稿日時: 2004-06-22 10:06
現在ORACLE,PL/SQLの勉強中で,
以下の問題にぶつかってしまい,困っています。
宜しかったらご教授お願いいたします。

------------------------------------------------------
@(SQL文)
SELECT
 A_TBL.TS_KENM_NO ,
 A_TBL.TISK_JS_D ,
 COUNT(*) AS CNT1
FROM
 A_TBL
GROUP BY
 A_TBL.TS_KENM_NO,A_TBL.TISK_JS_D
HAVING
 A_TBL.TISK_JS_D IS NULL
-------------------------------------------------------
A(現状)
TS_KENM_NO | TISK_JS_D | CNT1
1000001   |        |    8
1000003   |        |    2
1000004   |        |    2
-------------------------------------------------------
B(欲しい結果)
TS_KENM_NO | TISK_JS_D | CNT1
1000001   |        |    8
1000002   |        |    0
1000003   |        |    2
1000004   |        |    2
-------------------------------------------------------
現状は,Aのように,TISK_JS_DがNULLではないものは
TS_KENM_NOが取得できません。
そうではなく,Bのように検索結果0件の場合CNT1="0"を
取得したいのです。
宜しくお願いいたします。





[ メッセージ編集済み 編集者: ひろ 編集日時 2004-06-22 10:17 ]

[ メッセージ編集済み 編集者: ひろ 編集日時 2004-06-22 10:21 ]

[ メッセージ編集済み 編集者: ひろ 編集日時 2004-06-22 10:23 ]

[ メッセージ編集済み 編集者: ひろ 編集日時 2004-06-22 10:25 ]
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-06-22 10:48
忙しくて仕事が嫌になっちゃうよ〜って事で。
休憩を兼ねて(変?)考え方だけを返答致します。

まず、「どうしたいか?」それには「どうしたらいいか?」
をイメージする必要があります。

「どうしたいか?」はOKの様ですね。
で提示の内容でやったが駄目だった。って事で、
まず提示の方法では、何故0表示が提示で出来ないのかを
理解する必要があります。提示のSQL は、

 1.「A_TBL」に存在する、情報を集約し
 2.「TISK_JS_D」が「Null」のもののみを表示しないさい

と指示している訳です。つまり、要望に対してSQL君からすれば、

 3.上記1に対しては、「A_TBL」に無ければ知らね〜よ!、
 4.上記2に対しては、「A_TBL」にあっても、
   「TISK_JS_D」が「Null」だけを表示しろって言ったのはあんたでしょ?

と生意気にも反抗している結果な訳です。(どっちかな?)
で「どうしたらいいか?」と来る訳ですが、ひろさんの依頼で抜けている事は
「表示すべき軸」を提示していない訳です。逆に考えれば、「指定の軸毎で
集計しないさい。」とSQL君に依頼すれば宜しい訳です。

 5.上記1に対しては、TISK_JS_Dを管理しているテーブルを先に抽出し、
   その検索結果をキーとして集計する。

 6.上記2に対しては、上記5の後に「TISK_JS_D」が「Null」の条件で
   集計する事になります。

技術的に話せば、

 7.上記5は、「外部結合」&「副問合せ」の合わせ技で解決。
 8.上記6も、「外部結合」&「副問合せ」の合わせ技で解決。

 但し、上記8に付いては「count関数」自体で「TISK_JS_D」が「Null」ならば
 集計しなさいと命令する方が、カッチョエエです。

 さんぷる:count(decode(TISK_JS_D,Null,1,Null))

 ※上記例の 1 はNull 以外なんでも良し。


追記(オヤジの忠告)

 SQL文を記述する際は、処理対象となるテーブルが各値を
 どの様に管理しているか確認しましょ。

 SQL文は図を描く癖を付けましょう。(妄想でもよろしげ。)

# 編集で追記。
 そ〜言えば、SQL文の図式表現技法って出て来ないね?
 何でだろうね?COBOLで言えば複数ジョブと同等の処理をしている事もあるのに...

# 編集-修正
 4番の説明が逆だったので訂正


[ メッセージ編集済み 編集者: はにまる 編集日時 2004-06-22 11:11 ]
七味唐辛子
ぬし
会議室デビュー日: 2001/12/25
投稿数: 660
投稿日時: 2004-06-22 11:24
引用:

はにまるさんの書き込み (2004-06-22 10:48) より:

 SQL文は図を描く癖を付けましょう。(妄想でもよろしげ。)

[ メッセージ編集済み 編集者: はにまる 編集日時 2004-06-22 11:11 ]


SQLは集合を扱う言語だから 概念的にはベン図できると思う
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2004-06-22 11:58
引用:

@(SQL文)
SELECT
 A_TBL.TS_KENM_NO ,
 A_TBL.TISK_JS_D ,
 COUNT(*) AS CNT1
FROM
 A_TBL
GROUP BY
 A_TBL.TS_KENM_NO,A_TBL.TISK_JS_D
HAVING
 A_TBL.TISK_JS_D IS NULL
-------------------------------------------------------
A(現状)
TS_KENM_NO | TISK_JS_D | CNT1
1000001   |        |    8
1000003   |        |    2
1000004   |        |    2
-------------------------------------------------------
B(欲しい結果)
TS_KENM_NO | TISK_JS_D | CNT1
1000001   |        |    8
1000002   |        |    0
1000003   |        |    2
1000004   |        |    2
-------------------------------------------------------
現状は,Aのように,TISK_JS_DがNULLではないものは
TS_KENM_NOが取得できません。
そうではなく,Bのように検索結果0件の場合CNT1="0"を
取得したいのです。
宜しくお願いいたします。



A_TBLのTS_KENM_NOの値には
1000001   
1000002   
1000003   
1000004   
が入っていて、それぞれの値を持つレコード件数を知りたいのでしょうか?
そうだとしたら、
SELECT
 A_TBL.TS_KENM_NO ,
 nvl(A_TBL.TISK_JS_D,'null'),
 COUNT(nvl(TBL.TISK_JS_D,0)) AS CNT1
FROM
 A_TBL
GROUP BY
 A_TBL.TS_KENM_NO
ではどうでしょう?
推測+環境がないので確認してないので、違っていたらごめんなさい。

[ メッセージ編集済み 編集者: 夏椰 編集日時 2004-06-22 12:00 ]
ひろ
ベテラン
会議室デビュー日: 2003/12/26
投稿数: 97
投稿日時: 2004-06-22 12:03
SQLの複合問い合わせを利用することにより解決できました。
はにまるさん,夏椰さんご解説をいただき誠にありがとうございました。

はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-06-22 13:21
引用:

七味唐辛子さんの書き込み (2004-06-22 11:24) より:
SQLは集合を扱う言語だから 概念的にはベン図できると思う


べ、、べん図?って何...(ぐ〜ぐる調査中)
お!集合を表記する図を「ベン図」と言うのですね...勉強不足

引用:

夏椰さんの書き込み (2004-06-22 11:58) より:
SELECT
 A_TBL.TS_KENM_NO ,
 nvl(A_TBL.TISK_JS_D,'null'),
 COUNT(nvl(TBL.TISK_JS_D,0)) AS CNT1
FROM
 A_TBL
GROUP BY
 A_TBL.TS_KENM_NO


SQL文を見ただけでお伝え致しますが、
 1.TBL.TISK_JS_D での値で Null以外もカウントします。
 2.Select句の2行目「nvl(A_TBL.TISK_JS_D,'null'),」が
   集計キーでも無く、グループ関数を使っていないので文法エラーになります。
 3.A_TBL.TISK_JS_D が Null以外も表示される。(これはご愛嬌)
となります。

はにまる例1
コード:

select
  軸TBL.軸キー,
  count(A_TBL.TS_KENM_NO) as CNT1
from
  (
    select
     distinct A_TBL.TS_KENM_NO as 軸キー
    from
     A_TBL
  ) 軸TBL ,
  A_TBL
where
  軸TBL.軸キー = A_TBL.TS_KENM_NO (+)
and A_TBL.TISK_JS_D IS NULL
gourp by
  A_TBL.TS_KENM_NO
;


 説明:軸を求めるSELECT結果を用いて、集約する方法

はにまる例2:
コード:

select
  A_TBL.TS_KENM_NO,
  A_TBL.TISK_JS_D
  count(decode(A_TBL.TISK_JS_D,NULL,1,NULL)) as CNT1
from
  A_TBL
gourp by
  A_TBL.TS_KENM_NO,
  A_TBL.TISK_JS_D
having
  A_TBL.TISK_JS_D IS NULL
;


 説明:そのまま集計して件数取得時に条件判断を行う。
    その後に having句 で無駄なレコード(A_TBL.TISK_JS_D IS NOT NULL)を排除する。

基本的には、解り易い&変更に強い理由で前者をお奨めします。

# 同じく構文チェック及び結果チェックはしておりません。(てへ
# また要求やデータ値によって意図せぬ結果になりますので御注意を

引用:

ひろさんの書き込み (2004-06-22 12:03) より:
SQLの複合問い合わせを利用することにより解決できました。
はにまるさん,夏椰さんご解説をいただき誠にありがとうございました。


出切れば解答結果のSQL文を載せて下さい。
その方が、後で当スレッドを閲覧する方にとって役に立ちますので。

# って私も@IT会議室のお仕事(某スレッドのまとめ)を放置している状態ですが

# 編集-追記
 3.A_TBL.TISK_JS_D が Null以外も表示される。(これはご愛嬌)

 これは、私の前投稿の「A_TBL.TISK_JS_D で Null以外が表示されない問題?」
 に対する対応ですね...失礼致しました。 m(_ _)m

 では、リアルのお仕事を開始します。でわ、でわ


[ メッセージ編集済み 編集者: はにまる 編集日時 2004-06-22 13:37 ]
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2004-06-22 14:06
引用:


SQL文を見ただけでお伝え致しますが、
 1.TBL.TISK_JS_D での値で Null以外もカウントします。
 2.Select句の2行目「nvl(A_TBL.TISK_JS_D,'null'),」が
   集計キーでも無く、グループ関数を使っていないので文法エラーになります。
 3.A_TBL.TISK_JS_D が Null以外も表示される。(これはご愛嬌)
となります。


うわっ、失礼しましたm(__)m
やっぱり、Oracle環境がほしい・・・(T-T)

[ メッセージ編集済み 編集者: 夏椰 編集日時 2004-06-22 14:06 ]
ひろ
ベテラン
会議室デビュー日: 2003/12/26
投稿数: 97
投稿日時: 2004-06-23 13:57
返信遅くなり,申し訳ありません。
私は以下のプログラムで解決しました。
(はにまるさんの例と同じです。)
ありがとうございました。
--------------------------------------------------------
select
  A_TBL.TS_KENM_NO,
  A_TBL.TISK_JS_D
  count(decode(A_TBL.TISK_JS_D,NULL,1,NULL)) as CNT1
from
  A_TBL
gourp by
  A_TBL.TS_KENM_NO,
  A_TBL.TISK_JS_D
having
  A_TBL.TISK_JS_D IS NULL;
-----------------------------------------------------------



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