SQLの構文についての困りごと

このQ&Aのポイント
  • SQLの構文についてAccess2007、Windows7環境で困っています。自分の思った結果が得られず、間違いがあるはずなのですがわかりません。
  • 顧客マスタと注文リストのテーブルで、注文リストの顧客IDと送付先IDを顧客マスタのIDと関連付けたいです。SQL文を記述しましたが、特定のIDのみ正常に抽出され、他はデータ数分だけ表示されます。
  • 自分の頭の中では、まず顧客に依頼されて送付したものを抽出し、それに店舗から顧客に直接送付したものを追加で抽出するイメージです。しかし、特定のID以外はデータ数分だけ表示されてしまいます。どこが間違っているのかわかりません。
回答を見る
  • ベストアンサー

SQLの構文につきまして

Access2007、Windows7環境で SQLで自分の思ったとおりの結果が得られず困っています。 私の考え方に間違いがあるはずなのですが、自分ではよくわからない状態です。 お手数をお掛けして申し訳ないのですが 教えて頂けないでしょうか、よろしくお願いいたします。 ----------- -------------------- T顧客マスタ    T注文リスト ----------- -------------------- 顧客ID      注文ID 顧客ID 送付先ID  1          1    1     2  2          2    3     4  3          3    3     5  4          4    6     7  5          5    1     8  6  7  8 この2つのテーブルで、注文リストの顧客IDと送付先IDは 顧客マスタのIDを参照するようになっています 顧客IDの1には店舗情報が入っていて 注文リストの顧客IDと、1から送られてきた送付先IDの注文履歴を取得しようと思い 次のようなSQL文を記述しました SELECT T1.顧客ID, T2.氏名, T1.発送先ID FROM T注文リスト T1, T顧客リスト T2 WHERE T1.顧客ID = T2.顧客ID AND T1.顧客ID = [履歴を抽出したいID] or ( T1.顧客ID = 1 AND T1.発送先ID = [履歴を抽出したいID] ) 自分の頭の中では、まず顧客に依頼されて送付したものを抽出して それに店舗から顧客に直接送付したものを追加で抽出し 顧客IDだとわかりづらいので顧客IDで結合して氏名を表示してるイメージです その後、発送先の氏名も出すつもりです ここで、抽出したいIDが注文リストの顧客IDにある場合は正常に抽出できるのですが なぜか、1から送付されたID、上だと8などの場合、顧客ID:1 発送先ID:8 のセットで 顧客マスタの数分ずらずらと8件表示されてしまいます なぜ同じデータが顧客マスタのデータ分ずらずらと表示されるのかが わからないのです。自分の中では1件だけ表示されるつもりなのですが。 この仕組みについて教えていただけないでしょうか どこか根本的に考え方を間違っている気はするのですがよくわからない状態です よろしくお願いいたします。

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

  • ベストアンサー
回答No.1

> SELECT T1.顧客ID, T2.氏名, T1.発送先ID FROM T注文リスト T1, T顧客リスト T2 WHERE > T1.顧客ID = T2.顧客ID AND T1.顧客ID = [履歴を抽出したいID] or > ( T1.顧客ID = 1 AND T1.発送先ID = [履歴を抽出したいID] ) T顧客リストはT顧客マスタの間違いだとして。 [履歴を抽出したいID]が8の場合、T1.顧客ID=8を満たすレコードはないので、「( T1.顧客ID = 1 AND T1.発送先ID = [履歴を抽出したいID] )」を満たすレコードが抽出されます。ここにはT2の条件がないので、T2のレコード数分抽出されるのです。 T注文リストとT顧客マスタをFROMに併記すると、全ての組み合わせが作成されます。 必要なのは、T注文リストの顧客IDに一致するT顧客マスタの組み合わせなので、先に対象とするテーブルを絞っておくほうがパフォーマンス的にも有利です。 FROMの部分を T注文リスト INNER JOIN T顧客マスタ ON T注文リスト.顧客ID=T顧客マスタ.顧客ID のようにします。 どのようなテーブルが作成されるかは、WHEREを付けずにSELECT *で抽出してみればわかります。 それを見て、SELECTに必要なフィールドとWHEREに書く条件を考えて見ましょう。

IsoPRD
質問者

お礼

教えて頂きありがとうございます 非常にわかりやすくしっくりきました。 先に、T1.顧客ID = T2.顧客ID AND T1.顧客ID = [履歴を抽出したいID] で見ている為、こちらに存在しない場合は、T2が含まれていないので T2のレコードが全て抽出されると、なるほど INNER JOIN に関しても、=で同じ結果になるものだと思ってました。 条件前に先に結合するんですね、確かにその方が処理も速そうです。 これですっきり前に進めそうです、どうもありがとうございました。

関連するQ&A

  • Accessのクエリについて教えてください。

    クエリで顧客名を入力するとその人のデータが表示されるようにしたいのですが、購入履歴がない人は表示されません。購入履歴のない人も全て表示させる方法を教えていただけますか? ちなみにSQLはこういう感じです。よろしくお願いします。 SELECT 顧客マスター.顧客ID, 顧客マスター.氏名, Sum(販売.販売額) AS 販売合計 FROM 顧客マスター INNER JOIN 販売 ON 顧客マスター.顧客ID = 販売.顧客ID GROUP BY 顧客マスター.顧客ID, 顧客マスター.氏名 HAVING (((顧客マスター.氏名) Like [顧客名字を入力してください] & "*"));

  • SQLについて

    以下、SQL作成に困っております。 お助けください。 環境 sqlserver2008 t-sql ※番号はSQLの文中と関連付けしております。 1には顧客の情報を保持 2には顧客と店舗を結び付け資料送付対象の情報を保持 3には2の送付済み情報を履歴として保持しています。 実施したい事は 1と2を関連付けして、資料の送付対象の店舗を一覧表示したい 1と3を関連付けして、2に無いのに送付してしまった。 送付間違いを一緒に表示したいのです。 以下の、SQLの前に 1、2の情報にUNIONして 3だけの情報から2をNot Existsを使用して 抽出しておりましたが、保守性が悪いのでUNIONを使用しないで との話があり以下を作成しました。 困っていることですが 3のon句の記述に困っています。 以下のSQLでは資料送付済みの情報が表示されません。 3のon句を on 資料送付済み.顧客CD = お客さん情報.顧客CD and 資料送付済み.年度 = お客さん情報.年度 に置き換えると、お客さん情報に店舗CDが存在しない為、 全組合せ?になってしまい、実データより膨大な出力結果になってしまいます。 UNIONをしないで正しい結果を出力したいです。 お助けください。 declare @年度 varchar(4) = '2011', @店舗CD varchar(6) = '' SELECT , お客さん情報.年度 , お客さん情報.顧客CD , お客さん情報.顧客名 , 店舗への送付情報.店舗CD , 資料送付済み.店舗CD AS 店舗CD2 , 店舗マスタ.店舗名 , 送付ステータス = case when 店舗への送付情報.店舗CD = NULL and 資料送付済み.店舗CD != NULL then '送付間違い' else '' end FROM (select * from お客さん情報 where 年度 = @年度  ) お客さん情報 --1 メインテーブル left join (select * from 店舗への送付情報 where 年度 = @年度 ) 店舗への送付情報 --2 資料の送付対象店舗情報を保持 on 店舗への送付情報.顧客CD = お客さん情報.顧客CD and 店舗への送付情報.年度 = お客さん情報.年度 left join (select * from 資料送付済み where 年度 = @年度 ) 資料送付済み --3 資料の送付済み情報を保持 on 資料送付済み.顧客CD = 店舗への送付情報.顧客CD and 資料送付済み.年度 = 店舗への送付情報.年度 and 資料送付済み.店舗CD != 店舗への送付情報.店舗CD left join 店舗マスタ on 店舗への送付情報.店舗CD = 店舗マスタ.店舗CD order by 店舗CD desc

  • 1回のSQL文で書く方法を教えてください。

    うまく説明できるかわかりませんが、よろしくお願いします。 送り状ファイル   登録番号   送り主コード   送り先コード 顧客マスタ   コード   氏名 というテーブルがあり、 [登録番号]から送り状ファイルを検索し、 該当するデータの[送り主コード]と[送り先コード]から顧客マスタを検索し、 顧客マスタの[氏名]を取得したいのですが、 どのようなSQL文を書けばよいのでしょうか? 検索結果が   登録番号    ← 送り状ファイル   送り主コード  ← 送り状ファイル・顧客マスタ   送り主氏名   ← 顧客マスタ   送り先コード  ← 送り状ファイル・顧客マスタ   送り主氏名   ← 顧客マスタ としたいのです。 1回のSQL文で可能でしょうか?教えてください。

  • SQLでのレコードの抽出について。

    SQLでのレコードの抽出について。 ExcelのVBAを利用してOracleに接続し、必要なデータのみを抽出したいと考えています。 目的のレコードの抽出じたいには成功しているのですが、 他にも多数の処理を前後で行うのでなるべく高速に処理ができればと考えています。 そこでSQL、VBに詳しい方に作成したコードを見ていただき、もっと高速に処理ができるよう ご教授していただければと思います。 前置きが長くなりましたが、以下に作成したSQLと状況を記載します。 テーブル : t1会議マスタ フィールド: f11部門コード、f12会議NO、f13会議名、f14開催日、その他… テーブル2 : t2会議履歴 フィールド: f21部門コード、f22会議NO、f23出席者CD、その他… というテーブルがあり、ある出席者をもとに その出席者が出席した一番新しい会議の「会議名」「開催日」を取得したいのです。 そこでSQLを作成し、目的のレコードのみを表示するよう作成したのが以下のものです。 SELECT t1会議マスタ.f14開催日 t1会議マスタ.f13会議名 FROM t1会議マスタ INNER JOIN t2会議履歴 ON t1会議マスタ.f11部門コード = t2会議履歴.f21部門コード AND t1会議マスタ.f12会議NO = t2会議履歴.f22会議NO WHERE t1会議マスタ.f14開催日 IN ( SELECT MAX(t1会議マスタ.f14開催日) FROM t1会議マスタ INNER JOIN t2会議履歴 ON t1会議マスタ.f11部門コード = t2会議履歴.f21部門コード AND t1会議マスタ.f12会議NO = t2会議履歴.f22会議NO WHERE t2会議履歴.f23出席者CD = (変数)   AND t2会議履歴.f21部門コード = (???) ) GROUP BY t1会議マスタ.f14開催日, t1会議マスタ.f13会議名 以上です。 もっとシンプルかつ高速に行えればと思います(SQLで完全に絞り込まなくてももっと早い方法があればVBAなどで抽出してもかまいません)。 よろしくお願いいたします。

  • この場合のSQL構文を教えてください(MYSQL5.0)

    お世話になります。下記の場合どうしたらできるかどうか教えてください。 ・商品リストテーブル  商品ID(int primary key auto_increment )  商品名(char) ・受注リストテーブル  受注ID(int primary key auto_increment )  商品ID(int)  注文者(char) 上記のように二つのテーブルに分かれています。 (1)新商品の注文が入ると、商品リストテーブルにレコードがINSERTされ 受注リストにも同時にINSERTされるとします。 (2)すでに商品リストテーブルに登録済みの商品名の場合は受注リストテーブルのみINSERTされます。 この場合、商品リストの商品IDは自動インクリメントされるので問題ないですが、受注リストの商品IDはインクリメントされません。 商品リストに新レコードができると、このリストの商品IDは新しい番号がふられますが、この新しくできた番号を受注リストの商品IDに同時にいれたいのです。 ○方法として 二つのテーブルをJOINしてレコードをINSERTできるのならしたいのですが、どうゆうSQL文を書けばいいのかわかりません。 またその方法以外にとりあえず商品リストテーブルにだけINSERTしてそのタイミングで受注リストテーブルにトリガでINSERTとかする方法もありなんでしょうか? できればJOINした方にINSERTする方法でやりたいのですが、無理なら後者のほうでもいいんですが・・・。 SQL文わかる方どうかよろしくお願いいたします。

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

    SQL初心者です。ご質問させていただきます。 得意先マスタ(得意先CD、得意先分類CD、得意先名)←T [得意先分類CDは重複] 得意先分類マスタ(得意先分類CD、得意先分類名)←B 売上履歴(得意先CD、売上金額)←U というようなマスタが存在した場合に得意先分類CDで集計して、 (得意先分類CD、得意先分類名、売上金額)というようなデータを抽出したくて、下記のようなSQLを作成したのですが、うまくいきません。 SELECT U.得意先分類CD,B.得意先分類名,U.売上金額 FROM T,B,U WHERE T.得意先CD = U.得意先CD AND T.得意先分類CD = B.得意先分類CD GROUP BY B.得意先分類CD  よろしくお願いいたします。

  • Accessで

    以下のようなSQLの結果に、なぜか"々"が含まれている佐々木や奈々子なども抽出されます。"々"が含まれないようにするにはどのようなSQLにしたら良いのでしょうか?宜しくお願いします。 SELECT [T_顧客情報].[氏名] FROM [T_顧客情報] WHERE ((([T_顧客情報].[氏名]) Like "*ー*")); 動作環境 Access2003 SP1 WindousXP HomeEdition SP2

  • 複数のテーブルの重複データを抽出するには

    現在 テーブル T_2011,T_2010,T_2009 の3つのテーブルがあり、それぞれには同じ形式の顧客情報が入っています。 例えば 顧客id,氏名,住所 この時、 T_2011には2011年に購入履歴のある方 T_2010には2010年に購入履歴のある方 T_2009には2009年に購入履歴のある方 のデータが入っております。 そこで、毎年購入がある方を抽出したいのですが どうすれば可能でしょうか? もちろん1つのテーブルに集めて、重複チェックをすれば 出るのですが、今後テーブル数が増えたり、2011年と2090年に 購入のある方など様々な形での抽出をする可能性があるため クエリなどを利用し一発で抽出する方法があればと考えて おります。 もちろん検索等を行い似たような例はあったのですが ちょっと理解ができなかったためご質問させて頂きました。 宜しくお願いいたします。 重複チェックのキーは、顧客IDとなります。 環境は、windowsXP、access2000となっております。

  • SQLの作成について

    以下のSQLが作りたいのですが 作れなくて困っています。 有識者の方、お助けください。 環境:SqlServer2008 ★詳細説明 テーブルA、B、Cがあるとします。 A-B 1対1 B-C は1対N A,B,Cは全て検索・表示対象になります。 A-Bに対する検索表示は問題ないのですが Cの発送区分(1:未発送 2:発送済み)を検索条件と するSQL作成に悩んでおります。 ★テーブル・構成データ A 年度 顧客CD 顧客名称 2010 1000 A社 2010 1001 B社 2010 1002 C社 2010 1003 D社 B 年度 顧客CD サービス開始日 2010 1000  2011/04/1 2010 1001  2011/04/2 2010 1002  2011/04/3 2010 1003  2011/04/4 C 年度 顧客CD 部署 発送区分 発送日 2010 1000 A 1 2010 1001 A 1 2010 1001 B 2 2010/10/11 2010 1001 C 2 2010/10/12 2010 1003 D 1 2010 1003 D 2 2010/10/20 ★実現したいSQL 1.発送区分に検索条件を設定しない場合   年度 顧客CD 発送区分 発送日   2010 1000 1   2010 1001 2 2010/10/12   2010 1002 1   2010 1003 2     2010/10/20 2.発送区分を未発送   年度 顧客CD 発送区分 発送日   2010 1000 1   2010 1002 1 3.発送区分を発送済み   年度 顧客CD 発送区分 発送日   2010 1001 2 2010/10/12   2010 1003 2 2010/10/20 1~3を1回のSQLで実行したいのですが 実現できておりません。 よろしくお願いします。

  • oracle SQL

    以下のようなことを実現する方法についてお教え頂きたいです。 ■テーブル [XXXマスタ] ID char(8) 上記のテーブルにはIDという項目があるのですが、このテーブルで 使用していないIDのみをSQLで抽出できないかと考えております。 ただし、なるべくならワークテーブルのようなものは利用せずに 行いたいと思っております。 いい方法があれば教えていただきたいです。