SQLによる状態別データ取得方法

このQ&Aのポイント
  • 初心者の方に向けて、状態によって変わるデータを取得するSQLの書き方について解説します。状態が1,2,3の場合はデータを取得し、4の場合は取得しないように条件を設定します。
  • みかんTテーブルと状態Tテーブルを結合し、みかんTの状態列と状態Tの状態連番列を照合します。みかんTの状態が1,2,3の場合のみデータを取得し、4の場合は取得しないようにします。
  • 具体的には、SELECT文でみかんTの連番と入荷日を指定し、FROM句でみかんTテーブルを指定します。INNER JOINを使用して、みかんTの状態列と状態Tの状態連番列を照合します。WHERE句でみかんTの状態が1,2,3の場合のみ取得するように条件を指定します。
回答を見る
  • ベストアンサー

状態によって、取得したいデータをかえたい場合のSQLについて

状態によって、取得したいデータをかえたい場合のSQLについて 初心者で困っています。 以下は、状態が1,2,3の場合はデータを取得し、4の場合はデータを取得しないSQLです。 SELECT  みかん.連番  みかん.入荷日 FROM  みかん  INNER JOIN 状態   ON みかん.状態 = 状態.連番 WHERE  みかん.状態 IN (1,2,3) みかんT 連番   入荷日    状態 1   2010/02/01  1 2   2010/02/03  3 3   2010/02/08  4 4   2010/02/09  1 5   2010/02/13  2 6   2010/02/18  3 状態T 状態連番  項目  1    良好  2    まぁまぁ  3    不良  4    破棄 これからが質問なのですが、 みかんTの連番3の状態が4の場合、状態3のデータ(みかんTでいう連番2,6)は取得したくありません。 そうするには、どう書き換えたらうまく動作するでしょうか・・・ 宜しくお願いいたします。。

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

  • ベストアンサー
  • ks0902
  • ベストアンサー率85% (6/7)
回答No.5

>にしますと、状態が1,3の場合は、1のみしか取得できません 「状態が1,3の場合」というのはみかんTに状態が1,3の データしかないという意味ですよね? この条件で「状態が1,3の場合は、1のみしか取得できません」 ということは他に原因があるかもですね。 ちなみに以下のselect文で期待している値は取れますでしょうか? SELECT  連番,  入荷日,  状態  FROM みかん  WHERE   (状態 IN (1,2)) OR   (状態 = 3 AND NOT EXISTS (select * from みかん where 状態 = 4));

akira0628
質問者

お礼

たびたびの御回答ありがとうございます。 WHERE みかん.状態 IN (1,2,3) AND NOT EXISTS ( SELECT * FROM みかん WHERE みかん.状態 IN (4)) 上記の記述で解決できました。 EXISTSを使うこと自体頭になかった(使い方もよくわかっていなかった)ため、 とても勉強になりました。 ありがとうございます(*´∀`*)

その他の回答 (4)

回答No.4

実機確認していませんが、条件式を次のようにしてみては? WHERE (SELECT 状態 FROM みかん WHERE 連番=3)=4 AND 状態<>3 OR (SELECT 状態 FROM みかん WHERE 連番=3)<>4 AND 状態 IN (1,2,3)

akira0628
質問者

補足

御回答ありがとうございます。 記述どおりにしてみますと、 ”サブクエリは複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後に続く場合や、サブクエリが 1 つの式として使われる場合は複数の値は許可されません。” というエラーが出ました。 もう少し、考えてみたいと思います。 ありがとうございます。

  • ks0902
  • ベストアンサー率85% (6/7)
回答No.3

だめでしたか・・・  0 = CASE みかん.状態     WHEN '3' THEN (SELECT COUNT(*) FROM みかん WHERE 状態 = 4)     ELSE 0    END select文  (SELECT COUNT(*) FROM みかん WHERE 状態 = 4) で0がかえってきてないでしょうね。 ちなみに  SELECT isnull(COUNT(*),0) FROM みかん WHERE 状態 = 4 って書換えてもダメでしょうか? ダメなようなら、条件を みかん.状態 IN (1,2) OR (みかん.状態 = 3 AND NOT EXISTS (select * from みかん 状態 = 4)) に変更してみるとどうでしょうか?

akira0628
質問者

補足

再度の御回答ありがとうございます。 SELECT文を >SELECT isnull(COUNT(*),0) FROM みかん WHERE 状態 = 4 にすると、逆に4のデータが取得されてきます。 後記の >みかん.状態 IN (1,2) OR >(みかん.状態 = 3 AND >NOT EXISTS (select * from みかん 状態 = 4)) にしますと、状態が1,3の場合は、1のみしか取得できません(´・ω・`) 再度の御回答なのに、解決できず申し訳ないです。 上記記述も考慮して、考えてみたいと思います。 ありがとうございます!

  • ks0902
  • ベストアンサー率85% (6/7)
回答No.2

sql serverがないので確認しておりませんが  AND  0 = CASE みかん.状態     WHEN '3' THEN (SELECT COUNT(*) FROM みかん WHERE 状態 = 4)     ELSE 0    END または  AND  0 = CASE     WHEN みかん.状態 = '3' THEN (SELECT COUNT(*) FROM みかん WHERE 状態 = 4)     ELSE 0    END のどちらかを条件に追加してください。

akira0628
質問者

お礼

御回答ありがとうございます。 上の条件を試してみましたが、状態4がないのに3が取得できません。。 下の条件はエラーが出ました。 この記述を基盤に色々といじってみようと思います。 ありがとうございます。

akira0628
質問者

補足

すみません、下の条件もエラーは出ませんでした。 しかし、どちらの処理も同じ結果で、 4が含まれている3は取得できないようになっていますが、 4がない場合は3が取得できませんでした。。

  • ks0902
  • ベストアンサー率85% (6/7)
回答No.1

>みかんTの連番3の状態が4の場合、状態3のデータ(みかんTでいう連番2,6)は取得したくありません。 >そうするには、どう書き換えたらうまく動作するでしょうか・・・ この条件は みかんTに状態が4のデータがある場合は状態4、3のデータ以外(状態1、2)を取得する みかんTに状態が4のデータがない場合は全てのデータ(状態1、2、3)を取得する ということでしょうか?

akira0628
質問者

補足

>みかんTに状態が4のデータがある場合は状態4、3のデータ以外(状態1、2)を取得する >みかんTに状態が4のデータがない場合は全てのデータ(状態1、2、3)を取得する その通りです。 説明不足ですみません・・・(汗

関連するQ&A

  • sqlのwhereで指定した条件の前後を取得したい

    テーブル=T) KEY DATA 001 あ 002 い 003 う 004 え 005 お SQL) SELECT DATA FROM T WHERE KEY = 003 ; 上記のSQLでは、「う」のデータしか取得できませんが、 「003」の前後1件、合計3件の「い」「う」「え」を取得する方法を教えて下さい。 ちなみに、 SELECT DATA FROM T WHERE KEY >= 003 AND ROWNUM <= 2 と SELECT * FROM ( SELECT DATA FROM T WHERE KEY < 003 ORDER BY KEY DESC ) WHERE ROWNUM < 1 のUNIONでは上手く行きませんでした。 よろしくお願いします。

  • データがあれば○○なければのSQL

    基本的なことなのかもしれませんが・・・ AとBというテーブルがあり、あるタイミングでAを元にBを作成します。つまりBはデータがある場合とない場合があります。また、2つは関連番号で紐づいています。 Aテーブルを抽出したい時に、抽出条件は以下です。 ・Bテーブルのステータスが1であれば抽出 ・Bテーブルのステータスが0であれば非抽出 ・Bテーブルにデータがなければ抽出 INNER JOINだとデータがない時に抽出できないし、 WHERE句にCASE句を入れればいいのかなと思いましたが、テーブルにデータがあればなんて条件書けないしで詰まりました。 SELECTした結果に対して条件つけて抽出する手も思いつきましたが もっと美しいSQLがあれば教えてもらえないでしょうか。 環境はSQLServerです。よろしくお願いします。

  • inner joinをすると数がおかしくなります

    SQLのinner joinについてお教え下さい。環境はWin 7 MYQL5です。 t1テーブルのデータ ID,在庫 001,22 t2テーブルのデータ ID,出庫 001,17 001,3 SELECT Sum(t1.stock) AS `在庫` FROM t1 where id = '001' 上記SQLの結果は22と表示されます。 SELECT Sum(t1.stock) AS `在庫` FROM t1 INNER JOIN t2 on t1.id = t2.id where id = '001' とやると、結果が44になってしまいます。 なぜそんな結果になってしまうのでしょうか? 結果はt1.stockは在庫22なので、22と表示するようにしたいです。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • SQLの外部結合について教えて下さい

    いつもお世話になっています。 SQL構文の外部結合が分らなくて困っています。 どうか教えて下さい。 JSPからString Nam = (request.getParameter("param"));で値を受け取ってその値でT_Tableと一致するデータのSQLを実行します。 SELECT * FROM T_Table where ID='"+ Nam +"' order by 日付 desc この結果とT_TableAの「番号」というフィールドと一致する問い合わせのSQLが分りません。自分なりに考えて作りましたがHTMLの部分の表示だけでレコードが表示されないので間違っているのだと思います。 色々調べてみましたが該当のサンプルがなかったので困っています。 教えて下さい!宜しくお願い致します。 【自分で作成してみたSQLです】 テーブルはSQL Serverです。 "SELECT * FROM T_Table where ID='"+ Nam +"' INNER JOIN where ID='"+ Nam +"' ON [T_Table].[番号] = [T_TableA].[番号] order by 日付 desc"

    • ベストアンサー
    • Java
  • SQLについて

    以下のSQLを実行すると。 SQL実行中に以下のエラーが発生しました。 エラーコード:907 [Oracle][ODBC][Ora]ORA-00907: 右カッコがありません。 というエラーが表示されます。 どこがおかしいでしょうか? SELECT Q1.Pコード, Q1.Qコード, T1.E名称 A名称, T2.E名称 B名称, T3.E名称 C名称, T4.E名称 D名称, FROM ( ( ( ( SELECT Pコード, Qコード, Aコード, Bコード, Cコード, Dコード, FROM 報告書 WHERE Pコード = '0001' AND Qコード = '0001' AND ) Q1 INNER JOIN Eマスタ T1 ON Q1.Aコード = T1.Eコード ) INNER JOIN Eマスタ T2 ON Q1.Bコード = T2.Eコード ) INNER JOIN Eマスタ T3 ON Q1.Cコード = T3.Eコード ) INNER JOIN Eマスタ T4 ON Q1.Dコード = T4.Eコード ORDER BY Pコード, Qコード;

  • SQL文でのデータの取得が上手くいきません

    初めて質問させていただきます。 こちらのカテゴリで良いのか分からなかったのですが、よろしくお願いいたします。 SQL文を作成しているのですが、上手くいかず困っている状況です。 要件としてはテーブルAにユーザーの情報が格納されているのですが、 キーの一つとして世代(SEDAI_NO)(日付)を持っております。 今回取り出したいデータは該当ユーザーの処理日以前の最新のデータを 取得したいと思い以下のSQL文を作成しましたが、上手く行かず、最新世代を含むそれ以前の世代のデータを取得してきています。 どこがおかしいのでしょうか? よろしくお願いいたします。 【作成したSQL】 select * from テーブルA テーブルA’ where (USER_ID=該当のユーザーID) and (SEDAI_NO = (select max(SEDAI_NO) from テーブルA where SEDAI_NO = テーブルA’.SEDAI_NO AND 処理日 >= テーブルA'.SEDAI_NO)

  • SQLについて

    いつもお世話になっております。再度、解決できないSQLの問題が発生してしまいました。 識者の方よろしくお願いします。 環境:Oracle10g ストアドプロシージャ (1)参照テーブル  TEMP1(キー:契約番号、連番),TEMP2(キー:連番、契約種類CD),  タイプマスタ(キー:契約種類CD、タイプCD) (2)追加テーブル対象  契約明細(キー:契約番号,タイプCD) 実施したい事は(2)に保存されていない、(1)のデータを (2)に入れたいです。(1)のTEMP1、TEMP2には追加更新対象のデータが保存されています。 タイプマスタの参照はTEMP2にはタイプCDが存在していない為、 TEMP2.契約種類CDからタイプCDを導出しています。 実現出来ていないことなのですが NOT EXISTSの結果が伴わないので INSERTが正しく出来ずに困っております。 INSERT INTO 契約明細 ( 契約番号 ,タイプCD ) SELECT distinct A.契約番号 ,C.タイプCD FROM TEMP1 A INNER JOIN TEMP2 B ON A.連番 = B.連番 INNER JOIN タイプマスタ C ON B.契約種類CD = C.契約種類CD LEFT JOIN 契約明細 D ON C.タイプCD = D.タイプCD WHERE NOT EXISTS( select 'X' FROM TEMP1 INNER JOIN TEMP2 ON TEMP1.連番 =TEMP2.連番 INNER JOIN タイプマスタ ON タイプマスタ.契約種類CD = TEMP2.契約種類CD AND タイプマスタ.契約種類CD = C.契約種類CD INNER JOIN 契約明細 ON 契約明細.タイプCD = タイプマスタ.タイプCD AND 契約明細.タイプCD = D.タイプCD ) ; よろしくお願いいたします。

  • T-SQL(1件のみの取得)(再度)

    前回、-SQL(SQL Server2000)で対象データを一件のみ取得する場合、どのようにすれば良いでしょうか? 処理的に無理でしょうか? PL/SQLの"ROWNUMBER = 1"のような条件は使うことが出来ないのでしょうか? 上記の内容の質問をさせて頂いて、『TOP』が使用できるという回答をもらったのですが、この『TOP』は、SELECT文で取得しようとする場合 どのようにすれば良いでしょうか? ヘルプ等で調べてみたものの、良く理解できませんでした;; 取得内容としては、該当データ1レコード内の1フィールドを取得したいです。 /* PL/SQLから引用 */ SELECT 項目A   FROM テーブルA WHERE 項目A = 'AAA' AND 項目B = 10 AND ROWNUMBER = 1 この様な、取得方法を使用したいのですが、T-SQLではどのように行えばよろしいでしょうか? また、別の方法がありましたらお教えください。。。

  • SQL副問い合わせ内のエイリアス

    DEPARTMENTとEMPLOYEESのテーブルがあり、そこから社員のいない部署を取得しようとしているのですが、わたしの書いたSQLがうまく動きません。作動しない理由をご教授くだされば助かります。オラクル8.1.7.4.1で動作させなければならず、left outer joinが使えないところからの質問です。 データはこういう構造です(*がプライマリーキィを表す)。 DEPARTMENT: *DEPT__T, DEPT_NAME, .... EMPLOYEES: *EMPLOYEES__T, DEPT_NAME, ... これに対して、 select dept__t, (select count(*) from employee where department.dept__t = employees.dept__t) counter from department where counter = 0 というSQLで社員のいない部署を取ろうとしたのですが、ORA-00904: "COUNTER": invalid identifier.が返されてしまいます。 WHERE文にcounterというエイリアスではなくカラムそのものを書くと問合せが正常に作動するのですが、なぜでしょうか。オラクルのバージョンが古いことが原因でしょうか。

  • postgresqlの普通のSQLでデータが取得できません。

    postgresqlの普通のSQLでデータが取得できません。 下記のようなSQLがあります。 SELECT msiten AS kaisyacd,mtokuicd AS tokucd,mchikucd AS chikucd,mchikunm AS chikunm,nmakercd AS makercd,mdealer AS dealercd,mname1 AS name1,mname2 AS name2 FROM msitenmst LEFT JOIN ndealermst ON (mtokuicd = ntokuicd) AND (msitencd = nsiten) WHERE mtokuicd > 100000 (項目名・テーブル名など無理に変更していることをご了承ください。) これをvbaで流すとtokucdの値のみ取得できません。(0になります)他の項目は正しく取得できています。 Accessのクエリで同様のSQLを流しても正しく処理されます。 なぜ、このようなことが有り得るのでしょうか? 非常に困って居ます。 ヒントでもかまいませんので教えていただけないでしょうか? お願いいたします。