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

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

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

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

382閲覧

3つのテーブルから、在庫を導き出したい

unity3dbigginer

総合スコア65

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/06/18 02:42

編集2020/06/18 03:24

初めに

現在、3つのテーブル貸し出し履歴、文書目録、文書台帳から、在庫を導き出そうとしていますが、
うまくできません。

##テーブル

  1. 貸し出し履歴(rentalhistory)

イメージ説明

カラム説明
・ rental_id ・・・貸し出しID
・ member_id ・・・利用者ID
・ doc_id ・・・文書ID
・ rental_date・・・貸し出し年月日
・ deadline_date・・・返却期日
・ return_date・・・返却年月日

  1. 文書目録(doc_resister)

イメージ説明

カラム説明
・ doc_id ・・・文書ID
・ doc_isbn・・・isbn番号
・ arrival_date・・・入荷年月日
・ disposal_date・・・廃棄年月日

  1. 文書台帳

イメージ説明

カラム説明
・ doc_isbn・・・isbn番号
・ doc_name・・・文書名
・ sort_id・・・分類コード
・ author・・・著者
・ publisher・・・出版社
・ release_date・・・出版日

##実現したいこと
isbn番号、文書名、分類コード、著者、出版社、出版日、在庫

を表示させたいです。

##試したこと
在庫は、
本の数-まだ貸し出しされていない冊数=在庫だと思っているのですが、
なかなかうまくいきません。

sql

1select l.doc_isbn, l.doc_name, l.sort_id, l.author, l.publisher, l.release_date, count( l.doc_isbn) 2FROM doc_list l FULL JOIN doc_register d ON l.doc_isbn = d.doc_isbn FULL JOIN rental r ON d.doc_id = r.doc_id 3WHERE sort_id = ? and (rental_id is null or return_date is not null ) 4GROUP BY l.doc_isbn, l.doc_name 5

javaからsql文を実行しているので、プレースホルダーが1つありますが、ここには分類コード入れています。

実行結果は、
在庫ではなく、
本の数全体が出てきてしまいます。

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

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

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

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

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

Orlofsky

2020/06/18 03:10

質問のテーブル定義とデータはキャプチャではなく CREATE TABLE文とINSERT文で提示できた方が良いです。上記のMarkdownの [コード] を使ってね。
unity3dbigginer

2020/06/18 03:21

追加いたします。 ありがとうございます、
guest

回答2

0

ベストアンサー

集計を取る際のコツは、最終的な集計の単位にするまでを段階的に区切る事です。

質問の場合必要があるのは、doc_isbnをキーの一部に含むものだけですので、doc_resisterとrentalhistoryを結合したものを対象に集計します。

在庫を求めるには基準となる日が必要ですので現在日(current_date)を使用。
また、期間内に該当するかの判断で、日付型を前提にinfinityを使用してます。
※可能ならテーブルの初期値としてinfinityを設定しておくとNull判断が不要になりますのでお勧め。

SQL

1select l.*, coalesce(s.stock_num, 0) as stock_num, coalesce(s.rental_num, 0) as rental_num 2from doc_list l 3 left join ( 4 select doc_isbn 5 , sum(( 6 current_date 7 between arrival_date 8 and coalesce(disposal_date, 'infinity') 9 )) as stock_num 10 , sum((rental_date is not null and return_date is null)) as rental_num 11 from doc_resister d 12 left join rentalhistory r 13 on d.doc_id=r.doc_id 14 group by doc_isbn 15 ) s 16 on l.doc_isbn=s.doc_isbn

貸出可能数 = 在庫 - 貸出中数
でないかと思いますが明確ではないので、計算はせず、在庫と貸出中数を取得しています。

投稿2020/06/18 04:28

編集2020/06/18 05:36
sazi

総合スコア25327

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

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

unity3dbigginer

2020/06/19 03:24

ありがとうございます。 こちらを入力したところ、確認できました!
guest

0

FULL JOIN を INNER JOIN にしたらどうなりますか?

投稿2020/06/18 03:32

Orlofsky

総合スコア16417

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

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

unity3dbigginer

2020/06/18 04:27

INNER JOINにした場合、 正しくは2と出る本が、在庫1となってしまいます。
Orlofsky

2020/06/19 03:28

きちんとSQLの動作確認できるように、 上の方に >質問のテーブル定義とデータはキャプチャではなく CREATE TABLE文とINSERT文で提示できた方が良いです。上記のMarkdownの [コード] を使ってね。 ってのも書いたんですけど。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問