• ベストアンサー

下記の事を行うSQLがわかりません。

下記の事を行うSQLがわかりません。 テーブルAに名前の列と評価の列があります。 データは過去10年間の月毎の評価(1~5)です。 名前列には150人の登録者の名前が10年間の月の数だけ入っています。抽出したいのは評価が5を取っていない者の氏名です。 例 --------------------- 一朗 2 次郎 3 一朗 1 次郎 4 環境はwindows2000,Access2000です。 SQL始めたばかりなのでご指導おねがいします。

  • obone
  • お礼率51% (111/215)

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

  • ベストアンサー
  • galoon
  • ベストアンサー率28% (38/133)
回答No.3

ANo.1です。 かなり複雑になってしまいますが、条件は最後のwhereの部分に記述してください。 評価1~評価5はその評価をとった回数がカウントされていますので、とったことがあるは0より大( >0 )、とったことがないは0( =0 )になります。 内容に関するご質問は、また補足などでいただければ回答します。 SELECT 名前 FROM (SELECT 名前,sum(価1) as 評価1,sum(価2) as 評価2,sum(価3) as 評価3,sum(価4) as 評価4,sum(価5) as 評価5 FROM (SELECT 名前,1 as 価1, 0 as 価2, 0 as 価3, 0 as 価4, 0 as 価5 FROM テーブル1 where 評価 = 1 UNION SELECT 名前,0 as 価1, 1 as 価2, 0 as 価3, 0 as 価4, 0 as 価5 FROM テーブル1 where 評価 = 2 UNION SELECT 名前,0 as 価1, 0 as 価2, 1 as 価3, 0 as 価4, 0 as 価5 FROM テーブル1 where 評価 = 3 UNION SELECT 名前,0 as 価1, 0 as 価2, 0 as 価3, 1 as 価4, 0 as 価5 FROM テーブル1 where 評価 = 4 UNION SELECT 名前,0 as 価1, 0 as 価2, 0 as 価3, 0 as 価4, 1 as 価5 FROM テーブル1 where 評価 = 5) as A GROUP BY 名前) AS B WHERE 評価5 > 0 and 評価4 = 0;

obone
質問者

お礼

ありがとうございました。 成功しました。 2日考えていたので大変助かりました。 内容についてはいまから勉強します。

obone
質問者

補足

なんどもすみません。 名前列と評価列以外にも複数列があるのですが名前と一緒にその列の項目も表示させたい場合最初のSELECTの後の名前のところを*にすればいいのでしょうか。

その他の回答 (9)

noname#15703
noname#15703
回答No.10

 No.8の続きです。  といっても私はVBAは判らないのですが(苦笑)。  ダブルクオーテーションを2個づつにしてもだめですか? WHERE (((DCount(""*"",""[テーブルA]"",""[名前]='"" & [名前] & ""' AND [評価]="" & 4))=0)) OR (((DCount(""*"",""[テーブルA]"",""[名前]='"" & [名前] & ""' AND [評価]="" & 5))=0)); てな具合に。  すみません、ちょっと判りません。

obone
質問者

お礼

いろんなパターン試してみます。 ありがとうございました。

  • galoon
  • ベストアンサー率28% (38/133)
回答No.9

ANo.1,3,4,5です。 SQL文ひとつですむように修正してみました。 条件は文の後ろの方のMAX(A.E5)の部分です。 MAX(A.E1)、MAX(A.E2)、MAX(A.E3)、MAX(A.E4)、MAX(A.E5) は、0か1という値を返し、0は該当する評価を受けたことが「ない」、1は該当する評価を受けたことが「ある」ということをしめします。 後ろの数字が評価の数値を示しています。 下の文では、評価5を取得したことはないが、評価4を取得したことがあることを示します。 SELECT DISTINCT TABLEA.名前 , TABLEA.住所 FROM TABLEA INNER JOIN ( SELECT A.名前 FROM ( SELECT 名前 , 1 AS E1 , 0 AS E2 , 0 AS E3 , 0 AS E4 , 0 AS E5 FROM TABLEA WHERE 評価 = 1 UNION SELECT 名前 , 0 , 1 , 0 , 0 , 0 FROM TABLEA WHERE 評価 = 2 UNION SELECT 名前 , 0 , 0 , 1 , 0 , 0 FROM TABLEA WHERE 評価 = 3 UNION SELECT 名前 , 0 , 0 , 0 , 1 , 0 FROM TABLEA WHERE 評価 = 4 UNION SELECT 名前 , 0 , 0 , 0 , 0 , 1 FROM TABLEA WHERE 評価 = 5 ) AS A GROUP BY A.名前 HAVING MAX ( A.E5 ) = 0 AND MAX ( A.E4 ) = 1 ) AS B ON TABLEA.名前 = B.名前 ; これなら、そのままVBAでも使えると思うのですが、いかがでしょうか。 でも、ANo.8のkitasueさんの回答の方がスリムでいいですね。(^^;

noname#15703
noname#15703
回答No.8

 パフォーマンスがかなり落ちますので実用になるか判りませんが、次のクエリならば一発です。 SELECT テーブルA.* FROM テーブルA WHERE (((DCount("*","[テーブルA]","[名前]='" & [名前] & "' AND [評価]=" & 4))=0)) OR (((DCount("*","[テーブルA]","[名前]='" & [名前] & "' AND [評価]=" & 5))=0));

obone
質問者

補足

VBAでSELECT分を文字変数に入れてから発行しているのですが"[テーブルA]"のダブルコーテーションで文法エラーになるのですが。

noname#15703
noname#15703
回答No.7

 No.6の続きです。  すみません、私はVBAのことは、ほとんど解りません。  ただ、素人考えですが、クロス集計の部分はVBAで書かなくてもよいのではないでしょうか。  そのままクエリとして保存しておき、VBAで書くのなら2つめの集計クエリの箇所を書けばよいのでは?

obone
質問者

お礼

クロス集計はたしかに結果がでました。 ただVBAでQ_名前_評価を指定するとエラーになるので クエリの指定のしかたがあるのかもしれません。 調べてみます。

noname#15703
noname#15703
回答No.6

 横レス失礼します。  Access2000をお使いでしたらクロス集計クエリを利用されてはいかがでしょうか。  galoonさんのアイデアをお借りして、次のようなクロス集計クエリを考えました。クエリのSQLビューでペーストしたら、デザインビューに戻して構いません。 TRANSFORM Count(テーブルA.評価) AS 評価のカウント SELECT テーブルA.名前 FROM テーブルA GROUP BY テーブルA.名前 PIVOT テーブルA.評価;  これを「Q_名前_評価」という名前で保存します。  次に、以下の内容を、また新たなクエリとして登録します。これもSQLビューでペーストしたら、デザインビューに戻して構いません。 SELECT テーブルA.* FROM テーブルA INNER JOIN Q_名前_評価 ON テーブルA.名前 = Q_名前_評価.名前 WHERE (((Q_名前_評価.[4]) Is Null)) OR (((Q_名前_評価.[5]) Is Null));  このクエリを開くと、ご所望のリストになりませんか?

obone
質問者

補足

ご回答ありがとうございます。 説明不足だったのですが開発をすべてVBAで行っているのですが TRANSFORM Count(テーブルA.評価) AS 評価のカウント SELECT テーブルA.名前 FROM テーブルA GROUP BY テーブルA.名前 PIVOT テーブルA.評価; の部分はどう書いたらいいのでしょうか。

  • galoon
  • ベストアンサー率28% (38/133)
回答No.5

ANo.1,3,4です。 ざっと内容を見てみました。 これは、SQL文を入力したと考えていいのでしょうか? そうであれば、次の点を確認してみてください。 ・後半部分にSTATUS=3 という部分がありますね。これは、ST=3のミスでは? ・「ON TABLE.NAME = SELECT」の部分を「ON TABLE.NAME = (SELECT」とし、最後の「価2 = 0.NAME」を「価2 = 0).NAME」としてみてください。 もしかして、クエリとかを組み合わせない方がよかったんでしょうか・・・。 ちょっと複雑なクエリ文になってしまってわかりにくかったですね、申し訳ないです。

  • galoon
  • ベストアンサー率28% (38/133)
回答No.4

ANo.1,3です。 ちょっとクエリの数が増えますが次の方法が簡単だとおもいます。 (1)先のSQLをクエリとして保存する。(「クエリ1」とする。) (2)新しいクエリを次の内容で作成する。(「クエリ2」とする。) SELECT テーブルA.名前, {表示したい列名を列挙} FROM テーブルA INNER JOIN クエリ1 ON テーブルA.名前 = クエリ1.名前 (3)クエリ2を開く。 いかがでしょうか。

obone
質問者

お礼

やはりFORM句のエラーになります。 あまりお時間とらせるのは悪いので とりあえずテーブル2を追加しテーブル2にクエリー1の結果を保存しテーブル1とテーブル2でマッチングさせました。 ありがとうございました。 何か良い参考書、URL等ありましたらお教えください.

obone
質問者

補足

FORM句のエラーになります。 デバッグすると ?cmd.CommandText SELECT TABLE.NAME,TABLE.ADRESS FROM TABLE INNER JOIN SELECT NAME FROM (SELECT NAME,sum(価1) as 評価1,sum(価2) as 評価2,sum(価3) as 評価3,sum(価4) as 評価4 FROM (SELECT NAME,1 as 価1, 0 as 価2, 0 as 価3, 0 as 価4 FROM TABLE where ST = 1 UNION SELECT NAME,0 as 価1, 1 as 価2, 0 as 価3, 0 as 価4 FROM TABLE where ST = 2 UNION SELECT NAME,0 as 価1, 0 as 価2, 1 as 価3, 0 as 価4 FROM TABLE where ST = 3 UNION SELECT NAME,0 as 価1, 0 as 価2, 0 as 価3, 1 as 価4 FROM TABLE where ST = 4) as A GROUP BY NAME) AS B WHERE 評価2 = 0 ON TABLE.NAME = SELECT NAME FROM (SELECT NAME,sum(価1) as 評価1,sum(価2) as 評価2,sum(価3) as 評価3,sum(価4) as 評価4 FROM (SELECT NAME,1 as 価1, 0 as 価2, 0 as 価3, 0 as 価4 FROM TABLE where ST = 1 UNION SELECT NAME,0 as 価1, 1 as 価2, 0 as 価3, 0 as 価4 FROM TABLE where ST = 2 UNION SELECT NAME,0 as 価1, 0 as 価2, 1 as 価3, 0 as 価4 FROM TABLE where STATU S = 3 UNION SELECT NAME,0 as 価1, 0 as 価2, 0 as 価3, 1 as 価4 FROM TABLE where ST = 4) as A GROUP BY NAME) AS B WHERE 評価2 = 0.NAME 私の理解の範囲を超えているのでなにがおかしいのかわかりません。

回答No.2

select 名前 , 評価 from テーブルA where (テーブルA.評価 < 5) でいけませんか?

  • galoon
  • ベストアンサー率28% (38/133)
回答No.1

SELECT 名前 FROM テーブルA GROUP BY 名前 HAVING MAX(評価) < 5 でいかがでしょう?

obone
質問者

補足

早々の回答ありがとうございました。 私の説明がたりませんでしたが5を取っていない人はこれでいいのですが、5はあるけど4を取っていない人も検索しないといけないのですがその場合 テーブルA.評価 < 4 AND テーブルA.評価 >4 とかできるのでしょうか

関連するQ&A

  • ACCESS2000のSQLについて

    ACCESS2000のSQL文について質問です。 K情報テーブル:(支店(テキスト型),所属(テキスト),氏名(テキスト),ログ(テキスト),抽出件数(数値),処理日(日付型)) 支店 所属 氏名 ログ 抽出件数 処理日 ----------------------------------------- 関東 埼玉 太郎 A   50    2009/02/25 関西 大阪 次郎 B   15    2009/04/01 関東 埼玉 太郎 A   10    2009/03/05 関西 大阪 次郎 B   5    2009/04/06 東北 青森 三郎 C   2    2000/01/02 東北 青森 三郎 A   2    2000/01/02 ・ ・ ・ ----------------------------------------- 以上のテーブル情報を、SQL文にて抽出したいのですが、抽出条件が私には難解で解決の見通しが立ちません。ご教授をお願いします。 ***条件*** [ログ] = "A" のみ抽出。 現在日から過去3ヶ月前までのデータのみ抽出。 [氏名]ごと[ログ]の総合計。 [氏名]ごとの[抽出件数]の総合計。 [ログ]の総合計の上位30件を降順で。 順位にNo.をふる。 上記の条件で抽出したデータをを下記の作業テーブルに出力したと思っております。 作業テーブル:順位,所属,氏名,ログ件数,抽出件数 宜しくお願いします。

  • mysql でのsqlの書き方について教えてくださ

    mysql でのSQLの書き方についての質問です。 テーブルA(2項目 他既存データ) 氏名(姓) 氏名(名) 山田    太郎 山田    次郎 テーブルB(4項目) ふりがな氏名(姓) ふりがな氏名(名) 氏名(姓) 氏名(名) やまだ        たろう          山田    太郎 やまだ        じろう          山田    次郎 といった2つのテーブルがあります。 テーブルAに ふりがな氏名(姓) ふりがな氏名(名)  の2項目を追加してテーブルBのふりがなを 対応するテーブルAのふりがなに update したいのです。 内容がわかりにくくてすみません。

    • ベストアンサー
    • MySQL
  • SQLの質問です。

    SQLの質問です。 Access2003でのデータ操作で、 (1)2つのテーブルから一部列でのデータ重複があるものを除き、全件抽出 (2)テーブルは dテーブル No、販売先、日時、評価、金額 mテーブル 販売先(主キー)、店舗名 この二つのテーブルから全データを出力、ただし同じNoが重複しているデータは評価がA~Dのもの中で(E~F、空もある)日時が最新のもののみ出力をしたいのですが、教えていただけませんでしょうか、お願いします。

  • ACCESSのSQLで・・・

    ACCESS2003を使用しています。 氏名の苗字と名前の間にある空白をSQLで取り除きたいのですが、どのようにしたらいいのでしょうか? 教えて下さい。 そして空白を取り除いた後、空白なしの氏名と住所の入った別のテーブルと結合したいのです。 これも合わせて教えて下さい。 よろしくお願いします。

  • SQL ?で終わる

    アクセスのSQL文で、テーブルのフィールドの値が、最後が?で終わるものを抽出したいのですが SELECT テーブル.フィールド FROM テーブル WHERE (((テーブル.フィールド) Like "[*?]")); これだと1件も抽出されません。 Like "[*?]"が間違ってると思うのですが、どうすればいいでしょうか?

  • SQL文について教えてください。

    お世話になります。 テーブルを3つ作りました ユーザーテーブル:USER_MS USE_NO USER_NAME 001   太郎 002   次郎 003   三郎 品名テーブル:HINMEI_MS HINMEI_NO HINMEI_NAME 001    りんご 002    みかん 003    イチゴ 嫌いなものテーブル:KIRAI_TR KIRAI_NO USER_NO HINMEI_NO 001001  001   001 002003  002   003 002001  002   001 ※KIRAI_NO=USER_NO.HINMEI_NO と連結してプライマリーキーにした ここで、次郎の嫌いなものを抽出するときには $USER_NO = '002'; $SQL ="SELECT * FROM KITAI_TR A,HINMEI_MS B WHERE A.USER_NO = '$USER_NO'; で抽出できるのですが、 次郎の嫌いでない002みかんだけを抽出するSQL文がわからず苦慮しています。 以前、オラクルでSQLを使ったことがあったのですが、その時はFROM句の後に(SELECT * FORM・・・・) Bなどと書くと通ったのですがMYSQLでは通りませんでした。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • SQL文を教えてください

    SQL文を教えてください。 以下のテーブルがあります。 T入金 [ID] [名前] [金額] [入金日] 1, 山田, 25000, 2009/01/01 2, 佐藤, 5000, 2009/02/01 3, 山田, 30000, 2009/01/02 4, 佐藤, 45000, 2009/02/02 5, 佐藤, 10000, 2009/02/03 同じ人物で、入金額50000円に至ったときの入金日を 抽出したいと思っています。 上記データだと、 山田さんは入金日2009/01/02、 佐藤さんは入金日2009/02/02、 ということになります。 これを一つのSQL文で抽出できますでしょうか。 ご教授宜しくお願いいたします。 (Access2000のクエリで抽出しようとしていますが、Accessで無理ならSQL Server、MySQL、PostgreSQLでも可です)

  • SQL NOT INで抽出できない

    SQL NOT INで抽出できない SQLで条件抽出したいと思っています。テーブル1に「名前」というフィールドがあるとします。名前には「青木さやか」、「矢口真里」、「青山裕子」、「山田はな子」・・・などがあります。文字列の中に「青」や「子」が含まれていたら、抽出条件から外すといった処理をしたいと思っています。この例でいうと、「青木さやか」、「山田はな子」は抽出条件から外します。 そこで、 select 名前 from テーブル1 where 名前 NOT IN('青','子') といったら文を書きましたが、うまく動きません。どういった文にすればよいでしょうか?よろしくお願いいたします。

  • ACCESSのSQLで数値型に変換するには

    こんにちわ。今SQLの書き方が分からなくて大変困っております。 ACCESS2000で、テーブルが一つあるとします。 テーブルの内容は、氏名・点数の2項目だとします。 点数が50点より大きい人を抽出したいのですが、 項目は全てSTRING型にしないといけないため、 単純に比較できません。抽出した項目を数値型に 変換して、比較したいのですが、どのように書いたらいいのでしょうか。 SELECT  Shimei , CAST(Tensuu AS NUMERIC) FROM   Table1 WHERE   Tensuu > 50; このようなクエリを書いてみましたがエラーが出てしまいます。 ORACLEではTO_NUMBERなどの関数があると思うのですが、 ACCESSではどのようにしたらいいのでしょうか?? よろしくお願いします。

  • こんなSQL文はありませんか?

    環境:Access97 例えば以下のような社員名テーブルがあったします。 部署名|氏名 --------------- 経理部|田尾 --------------- 経理部|平野 --------------- 経理部|モッカ --------------- 営業 |谷沢 --------------- 総務部|大島 --------------- 総務部|上川 --------------- このテーブルを部署ごとにグループ分けして 以下のような形式で氏名を抽出したいのですが、 このようなことができるSQL文はありますでしょうか。 部署名|氏名1|氏名2|氏名3|・・|氏名n ---------------------------------------- 経理部|田尾 |平野 |モッカ ---------------------------------------- 営業 |谷沢 ---------------------------------------- 総務部|大島 |上川 宜しくお願いいたします。