• ベストアンサー

テーブルからのselectにおいてデータの有無により結果をわけたい

id | point ----+------- 1 | 10 2 | 9 3 | 5 .... というテーブルがあるとします. idを指定してpointを得たいのですが、そのidがこのテーブルに存在しない場合は空の結果ではなく0を返したいのです. plpgsqlなどを使いif文で場合分けすればできることはわかっているのですがSQL文だけで(それもできれば1文で)これを実現する方法はあるでしょうか? よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • baunce
  • ベストアンサー率66% (2/3)
回答No.7

変則的ですが、これでよければidがユニークでなくても大丈夫ですし、集合関数を使わなくてもOKです。 select dm.id,case when ex1.point is null then 0 else ex1.point end from (select ? as id) as dm left join ex1 on dm.id = ex1.id; ?を適当に変えてください。 chukenkenkouさんの発想はこれですよね。

yasumitu
質問者

お礼

おおっ、これはすごい。勉強になります。 chukenkenkouさんの発想からSQL文をつくることが自分にはできなかったのでとても助かりました。 ありがとうございました。

その他の回答 (6)

回答No.6

#5回答者です。 #5回答は、やりたいことを私の方で勘違いしていました。 失礼しました。

回答No.5

「存在しない」ものを検索したいなら、予め別表で用意しておくか、selectで一時的に作り、unionするしかありません。

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.4

No.1 です。 > ためしてみたら次のようにエラーとなってしまいました. う、 GROUP BY 句は WHERE 句より後が正しいかも知れません。 すみません。

参考URL:
http://www.postgresql.jp/document/pg815doc/html/sql-select.html
  • rinmane
  • ベストアンサー率56% (64/113)
回答No.3

お礼文ありがとうございます。 あ、そうですね。 WHERE id = あいでぃ にしてるんだから当然そうなりますね(汗) と言うことは… SELECT CASE WHEN COUNT(*) > 0 THEN point ELSE 0 END FROM ex2 WHERE id = 5 ですね。 ってもうCOALESCEで解決されてるんですね。 久々にSQL文、見たのでなんとなく回答しちゃいました。 申し訳ありません。

yasumitu
質問者

お礼

再度ありがとうございます。 なるほど、こんな書き方もできるのですね。勉強になりました。 ちなみに下のようにsum(point)として目的の結果を得ました。 SELECT CASE WHEN COUNT(*) > 0 THEN sum(point) ELSE 0 END FROM ex2 WHERE id = 5; ありがとうございました。

  • rinmane
  • ベストアンサー率56% (64/113)
回答No.2

SELECT id, CASE WHEN point IS NULL THEN 0 ELSE point END AS point FROM てーぶる WHERE id = あいでぃ こんな感じでしょうか。 CASE式はSQL-92から標準のようです。 以上、ご参考になりましたら幸いです。

yasumitu
質問者

お礼

ご回答ありがとうございます。 ただ、試してみると exam=# select id,case when point is null then 0 else point end as point from ex2 where id = 10; id | point ----+------- (0 rows) という具合に空行がかえってきました。なかなか厄介ですよね。

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.1

id が UNIQUE なら、 SELECT sum(point) FROM (テーブル名) GROUP BY id WHERE id = ? でしょうか。 該当 id が無い場合に NULL で無くゼロを返すためにはもうひと捻り必要かも知れません。

yasumitu
質問者

お礼

早速のお返事ありがとうございます. ただ、ためしてみたら次のようにエラーとなってしまいました. ちなみにpostgreSQL 8.3 です。 exam=# select sum(point) from ex2 group by id where id = 1; ERROR: syntax error at or near "where" LINE 1: select sum(point) from ex2 group by id where id = 1; 簡単そうで難儀な問題ということでしょうか。

yasumitu
質問者

補足

すみません.zxcv0000さんの回答をヒントに試していたら次のような案が見つかりました。幸いidはuniqueなのでこれでやってみようかと思います。 exam=# select coalesce(sum(point),0) as point from ex2 where id = 5; point ------- 0 (1 row) お騒がせ致しました.

関連するQ&A

  • あるテーブルの内容を基準にして違うテーブルを更新するSQL文

    教えて下さい。 あるテーブルに下記の内容があります。 ID│名称 ─┼─── 1│花 2│木 3│水 もうひとつのテーブルには、 ID│名称 ─┼─── 1│海 3│水 4│空 となっています。 最初のテーブルの全レコードを対象に、最初のテーブルのIDと同じ値がもうひとつの テーブルにある場合、もうひとつのテーブルをUPDATEし、存在しなければINSERTしたい です。 結果を ID│名称 ─┼─── 1|花 2│木 3│水 4│空 を期待しています。 このようにするSQL文を教えていただけませんでしょうか。 よろしくお願いします。

  • select の中の select

    SQL文で3つのデータを表示させようとしています。 ID、ポイント、登録日というデータです。 データベースには ID POINT IN_DATE 4 100 2004/10/01 ・・・ 4 150 2004/10/31 ・・・ 5 200 2004/09/01 ・・・ 3 150 2004/10/31 ・・・ 3 200  2004/10/01 このように入っている場合に、 IDが同じ物はグループ化して、その中で登録された一番新しいデータを各々抽出したいのですが、うまくいきません。 この場合に表示されるデータは 4 150 2004/10/31 ・・・ 5 200 2004/09/01 ・・・ 3 150 2004/10/31 ・・・ です。何かよい方法があれば教えてください。

  • Select文を教えて下さい

    select文についてお教えください。環境はAccess2003,Win XPで動かしています。 TABLE ID(INT),STOCK(INT) 001,100 001,200 001, 002,200 002,300 002,400 003,100 上記のようなテーブル、データがあります。 ■抽出したい行 001,100 001,200 ■抽出条件 STOCKに空がはいっている。 STOCKに空がはいっている行は選択しない。 STOCKに空がはいっているIDで、同一IDでSTOCKにデータがある行を抜き出したいです。 どのようにSQLを組み立てればよいかわかりません。 宜しくお願い致します。

  • 同じデータが結果として出てくるので困ってます

    他人が作ったものを修正中です。 現在↓ カラム ID NO1 NO2 NO3     1  12 23 34 2 12 3 12 23 $sql="SELECT ID FROM `SHOPLIST`"; $db = mysql_query($sql); while($db2 = mysql_fetch_array($db)){ ・・・・省略 } 結果抽出データは 1 1 1 2 3 3 なぜか6件です。 NO1,NO2,NO3に値が入っている数と重複するデータ数が同じです。 現在はif文を使ってIDが同じものは処理しないという動きです。 これをif文を使わずに、MySQLだけでIDが同じものは抽出しないと いうことはできるのでしょうか。 考え方だけでも教えて頂きたいです、宜しくお願い致します。   

  • SQLの質問です

    SQL初心者の質問です。下記のように違うdateを持つ同じgrade_idがいくつか存在するテーブルから、最新のdateのgrade_idを選択してその列の他の情報(point)も持って来たい場合、どんなSQL文が最適でしょうか?Disthinctを使ってもうまくできずに困っています…よろしくお願い致します。 id ・ date ・ grade_id ・ point 1 ・ 2008/05/01 ・ 1 ・ 6 2 ・ 2008/10/01 ・ 1 ・ 1 3 ・ 2000/08/08 ・ 2 ・ 2 4 ・2008/05/01 ・ 2 ・ 8

  • SQLの質問です

    SQL初心者の質問です。下記のように違うdateを持つ同じgrade_idがいくつか存在するテーブルから、最新のdateのgrade_idを選択してその列の他の情報(point)も持って来たい場合、どんなSQL文が最適でしょうか?Disthinctを使ってもうまくできずに困っています…よろしくお願い致します。 id date grade_id point 1 2008/05/01 1 6 2 2008/10/01 1 1 3 2000/08/08 2 2 4 2008/05/01 2 8

  • SQLのSELECT結果を縦から横に抽出する方法

    SQLのSELECT文について DB:MYSQL5.0 テーブルAとテーブルBを結合して テーブルAの項目と一緒(横)にテーブルBを抽出したいです。 どのようにすると実現できるのでしょうか? よろしくお願いします。 Aテーブル ID ITEM1 1 11111 2 22222 3 33333 4 44444 Bテーブル ITEM1 CNT KBN 11111 1    1 11111 2    2 11111 3    3 22222 4    2 22222 5    3 33333 6    3 出力結果 ITEM1 KBN1 KBN2 KBN3 11111  1   2   3 22222  0   4   5 33333  0   0   6 44444  0   0   0

  • 複数テーブルを合わせて総合ランキングを作りたいです

    以下の2つの相性テーブル(table_a,table_b)でサブクエリーを使わず期待する結果(ランキング)を得るSQLはあるでしょうか? 又、両方とも1万件になった場合結構重いでしょうか?うーん、1つのテーブルにした方が良いですか。。 ■table_a user match_user point test1 test2 2 test1 test3 2 ■table_b user_id match_user_id point test1 test2 2 test1 test3 4 ■期待する結果 総合マッチランキング 1. test3 (6point) 2. test2 (4point)

    • ベストアンサー
    • MySQL
  • 別テーブルを参照し、その内容を別のテーブルに書き込む

    2つのテーブルに存在しているデータを参照し、 取得したデータの結果を3つ目のテーブルに保存する処理をしているのですが // USERのUNIQUEとGAMEのGAME_NOはプライマリーキー select RATE from USER where UNIQUE = xxx select POINT from GAME where GAME_NO = yyy insert into HISTORY set COIN = RATE * POINT 今は一つの保存に対して3つのSQL文を使わなければいけないのですが、 うまいことこの3つのSQL文を一つか二つにつなげるということは出来ないものでしょうか?

    • ベストアンサー
    • MySQL
  • SQLの書き方

    わからないので質問をさせて頂きます。 テーブルAに、money、rank、name、IDと言うカラムがあります。 テーブルBに、IDとpointと言うカラム名があります。 テーブルAのIDを指定し、テーブルBに同じIDが存在する場合 テーブルAとBの値を取得するSQLを書いています。 Select テーブルA.money,テーブルA.rank テーブルA.name,テーブルA.ID,テーブルB.point FROM テーブルA,テーブルB Where テーブルA.ID = '5'; このように書くとmoney,rank,name、IDは重複して表示がされ pointに関してはすべてのpointが表示されてしまいます…。 重複するのでdistinctを使ったのですが うまくいかず…。 SQL初心者ですが、よろしければ教えてください。

    • ベストアンサー
    • MySQL