質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

1回答

1011閲覧

データの結合が上手く行かず、期待通りレコードが引けません。

wasi300

総合スコア66

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

1クリップ

投稿2020/09/25 20:52

編集2020/09/26 04:01

会社が利用する、顧客管理の仕組みを作っています。
見積書と請求書作成の機能も付いています。

見積書と請求書を顧客情報を結合して、1レコード毎に纏めて情報を出したいと思っています。

  • 見積書・請求書に顧客が紐づいていなくても出力したいです
  • 見積書・請求書、どちらか一方のデータがあれば出力したいです

各テーブルの関係

  • 見積書と請求書は紐づいているもの、紐づいていないものがあります
  • 見積書と請求書は、顧客データと紐づいているもの、紐づいていないものがあります
  • 見積書と請求書すべてに、システムを利用している会社(host)のIDが振られています
  • 見積書の請求書IDには、値が入っていません

テーブル構成は下記です。

  • estimate : 見積書テーブル
  • invoice : 請求書テーブル
  • host : システム利用会社テーブル
  • customer : 顧客テーブル

unionを使って、理想に近い形でデータが取得できましたが、
見積IDの重複が少し出てしまい、上手く行きません。
group byすると、nullもgroup byされるので、レコード数が期待よりだいぶ少なくなります。

SQL

1 2select * 3from 4 ( 5 select estimate.estimate_id, 6 estimate.invoice_id, 7 customer.customer_id 8 from estimate 9 left outer join 10 customer on estimate.customer_id = customer.customer_id 11 where 12 estimate.host_id = 1203507743 13 and 14 estimate.deleted_at is null 15 union 16 select invoice.estimate_id, 17 invoice.invoice_id, 18 customer.customer_id 19 from invoice 20 left outer join 21 customer on invoice.customer_id = customer.customer_id 22 where 23 invoice.host_id = 1203507743 24 and 25 invoice.deleted_at is null 26 ) as q1; 27

上記実行結果で見積もりIDの重複が無くなれば期待通りになります。

文字数制限のためテーブル生成のSQLとInsert文はgistにあげました。

すみませんが、どなたか分かる方いたら、教えていただけないでしょうか…。

=== gentaroさん指摘=============================================

「1レコード毎に纏めて」の意味を定義してください。

見積書・請求書を印刷できるWebページを作っています。
見積書・請求書はどちらかが削除されてても1行に全て出力します。

と。書いていて普通にJOINして、削除フラグをプログラムから見て
ボタンを出力する・しないすればいいだけだということに気が付きました。

SQL

1 2select estimate.estimate_id, 3 invoice.invoice_id, 4 estimate.deleted_at as a, 5 invoice.deleted_at as b 6from estimate 7left join invoice on estimate.estimate_id = invoice.estimate_id 8where estimate.host_id = 1203507743; 9

===============================================================

=== Orlofskyさん指摘=============================================

リンク先のINSERT文も各テーブル5件程度に削っては?そうすればここの質問にまとめられるのでは?

重複出る理由が分からず、何削っていいか分からないので、
今回はギブします。ごめんなさい。

少なくした結果を、codeで出すと分かりやすいですよというアドバイスだと思ってます。
どうもありがとうござました。

===============================================================

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2020/09/25 22:27

ひとつの見積書IDに対し、見積書→請求書への参照が不可能で、請求書→見積書への参照が可能となっているレコードがありますが、これは仕様ですか?データ欠落ですか? データ欠落だとすると、テーブル設計レベルで誤っていると思いますが。 また、上記のような場合に期待する出力はどんなものですか? 「1レコード毎に纏めて」の意味を定義してください。
wasi300

2020/09/26 02:57

>> Orlsofskyさん Insert文修正して、結果も書いてみます。ありがとうございます。 >> gentaroさん ご指摘ありがとうございます。 見積書IDで参照できない請求書はあります。 請求書IDで見積の参照はできません。見積書の参照は見積IDで行います。 どのレコードか教えていただけますでしょうか。 「1レコード毎に纏めて」については、質問修正します。
gentaro

2020/09/26 04:09

> と。書いていて普通にJOINして、削除フラグをプログラムから見て > ボタンを出力する・しないすればいいだけだということに気が付きました。 これは問題が解決したという意味ですか?
wasi300

2020/09/26 04:11

はい。解決しました。お騒がせしました。 顧客テーブルを考慮する必要がなかったことが抜けていました。 ありがとうございます。
gentaro

2020/09/26 05:56

なるほど。 ではご自身で回答を作成し、自己解決としてクローズしてください。
sazi

2020/09/26 07:17 編集

> 引用テキスト上記実行結果で見積もりIDの重複が無くなれば期待通りになります。 本当ですか?  invoiceのestimate_idでestimateを参照するとdeleted_atが設定されているもの(無効)のestimate_idも取得していますよ。 例えば、質問のSQLで取得される、 (estimate_id, invoice_id, customer_id)=(174710775,986426253,922361081) についてestimateのデータはdeleted_atが設定されています。
guest

回答1

0

ベストアンサー

見積書・請求書に顧客が紐づいていなくても出力したいです

見積書・請求書の顧客を使用するとして結合するかどうかは後回し。

見積書・請求書、どちらか一方のデータがあれば出力したいです

質問のSQLでは、Full joinが使用できない場合の、全外部結合の組み立てができていませんね。

A.請求書+関連する見積書:請求書→(lefto join)→見積書
B.見積書のみ:見積書→(lefto join)→請求書で請求書が無いもの
全体に対してそれぞれが補集合です。
Full Joinを使わない場合は、補集合をunion ALL します。
※補集合なので重なりませんからunion allします。

SQL

1 select invoice.estimate_id, invoice.invoice_id, invoice.customer_id 2 from invoice 3 left join estimate 4 on invoice.customer_id = estimate.customer_id 5 and invoice.estimate_id = estimate.estimate_id 6 and invoice.deleted_at is null 7 and estimate.deleted_at is null 8 where invoice.host_id = 1203507743 9union all 10 select estimate.estimate_id, invoice.invoice_id, estimate.customer_id 11 from estimate 12 left join invoice 13 on estimate.customer_id = invoice.customer_id 14 and estimate.estimate_id = invoice.estimate_id 15 and estimate.deleted_at is null 16 and invoice.deleted_at is null 17 where estimate.host_id = 1203507743 18 and invoice.invoice_id is null

追記

削除フラグを取得後に判断する

SQL

1 select invoice.estimate_id, invoice.invoice_id, invoice.customer_id 2 , invoice.deleted_at as invoice_deleted_at 3 , estimate.deleted_at as estimate_deleted_at 4 from invoice 5 left join estimate 6 on invoice.customer_id = estimate.customer_id 7 and invoice.estimate_id = estimate.estimate_id 8 where invoice.host_id = 1203507743 9union all 10 select estimate.estimate_id, invoice.invoice_id, estimate.customer_id 11 , invoice.deleted_at as invoice_deleted_at 12 , estimate.deleted_at as estimate_deleted_at 13 from estimate 14 left join invoice 15 on estimate.customer_id = invoice.customer_id 16 and estimate.estimate_id = invoice.estimate_id 17 where estimate.host_id = 1203507743 18 and invoice.invoice_id is null

投稿2020/09/26 07:38

編集2020/09/27 03:49
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wasi300

2020/09/27 03:38

SQL教えてくださりありがとうございます! 今回は、見積書・請求書をDeleteフラグ立ってても取得して、 プログラムで、Deleteフラグを見て、処理変えるようにします!
sazi

2020/09/27 03:54 編集

質問に追記されているSQLでも、全外部結合の結果になっていません。(請求書のみがありません) そもそも、自分で必要なパターンのテストデータを作成していないから、見落としが生じているんだと思います。
wasi300

2020/09/28 03:32 編集

追記に書いたものでは、見積IDと連携したものしか結果を貰えないので不十分でした…。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問