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

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

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

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

SQL

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

Q&A

解決済

3回答

495閲覧

InnerJoinでSQLをまとめたい

no1knows

総合スコア3365

MySQL

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

SQL

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

0グッド

0クリップ

投稿2019/04/25 04:05

編集2019/04/25 06:23

前提・実現したいこと

下記のテーブルを基にそれぞれのSELECT文を作成しました。
これを①+②ー③のようにまとめ、amountがマイナスのものを削除したレコードを取り出したいのですが、うまくできません。

MySQL

1 2①select MAX(id) AS `id` from t_transactions group by tran_grp; 3 4②select id from t_transactions where settle_grp IS not null; 5 6③select settle_grp from t_transactions where settle_grp IS NOT NULL group by settle_grp;

table

1id payment_date amount tran_grp settle_grp 2132 2019/7/1 20 132 NULL 3133 2019/7/1 -20 132 NULL 4134 2019/7/1 20 132 NULL 5135 2019/10/1 1000 135 NULL 6137 2019/10/1 1000 137 NULL 7138 2019/10/1 -1000 137 NULL 8139 2019/10/1 1000 137 NULL 9140 2019/10/1 -1000 137 139 10141 2019/11/1 300 137 139 11142 2019/11/3 700 137 139 12143 2019/11/3 -700 137 142 13144 2019/11/3 300 137 142 14145 2019/11/10 400 137 142 15

該当のソースコード

#①+②ー③の結果 id payment_date amount tran_grp settle_grp 134 2019/7/1 20 132 NULL 135 2019/10/1 1000 135 NULL 140 2019/10/1 -1000 137 139 141 2019/11/1 300 137 139 143 2019/11/3 -700 137 142 144 2019/11/3 300 137 142 145 2019/11/10 400 137 142
#最終的にほしいレコード id payment_date amount tran_grp settle_grp 134 2019/7/1 20 132 NULL 135 2019/10/1 1000 135 NULL 141 2019/11/1 300 137 139 144 2019/11/3 300 137 142 145 2019/11/10 400 137 142

試したこと

SQLを分割して、InnerJoinでつなげようと思いましたが下記エラーがでてしまいました。
どうぞよろしくお願いいたします。

MySQL

1#①+② 2 3 SELECT MAX(id) AS `id` from t_transactions group by tran_grp AS join1 4INNER JOIN select `id` from t_transactions where settle_grp IS not null AS join2 5 ON join2.id = join1.id;

発生している問題・エラーメッセージ

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS join1 INNER JOIN select `id` from t_transactions where settle_grp IS not null' at line 1

補足情報(FW/ツールのバージョンなど)

mysql 5.7

追記 ①+②ー③までをサブクエリを利用して作成できました。ここからマイナス分を削除しようと思います。

SELECT * FROM t_transactions WHERE t_transactions.id = ( SELECT MAX(id) FROM t_transactions AS tmp WHERE t_transactions.tran_grp = tmp.tran_grp ) or settle_grp IS not null and id NOT IN ( select settle_grp from t_transactions where settle_grp IS NOT NULL group by settle_grp );

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

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

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

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

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

no1knows

2019/04/25 04:34

失礼いたしました。エラーメッセージを追記しました。
guest

回答3

0

ベストアンサー

対象のテーブルが1つであるときに自身にむけてinnerjoinするのはあまりいいやり方とは言えません。

「うまくいかない」コードもサブクエリを利用されたほうが良いでしょう(エラーですし)
エラーなくすだけならこう。

sql

1select 2 * 3from 4 ( 5 SELECT 6 MAX(id) AS `id` 7 from 8 t_transactions 9 group by 10 tran_grp 11 ) AS join1 12 INNER JOIN 13 ( 14 select 15 id 16 from 17 t_transactions 18 where 19 settle_grp IS not null 20 ) AS join2 21 ON join2.id = join1.id 22;

フォーマットサービスを利用しました

エラー確認については構文チェックサービスを利用しました。


あとはこれで「想定通りの結果がでるか」ですけど、たぶんでない気がします。
SQLとかもそうですけど、一番内側から実行されていくものなので、順番を間違えると思わぬ結果が返ってきます。

「個々に動いているSQLをまとめる」というより、「どういう条件でデータを絞り込むか」という観点で考えてはいかがでしょうか?

投稿2019/04/25 04:42

m.ts10806

総合スコア80850

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

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

no1knows

2019/04/25 06:23

よい考え方をいただきありがとうございます。 まだ①+②ー③ができた段階ですが、徐々に期待するものができつつあります。
no1knows

2019/04/25 10:30

直接的な回答というより、考え方を教えていただいたので非常にためになったという視点でべすとあんさーとさせていただきます。
m.ts10806

2019/04/25 10:32

ヒントになったようでなによりです
guest

0

SQL

1create table tbl 2(id int,payment_date date,amount int,tran_grp int,settle_grp int null); 3 4insert into tbl values 5(132,'2019-07-01', 20,132,NULL), 6(133,'2019-07-01', -20,132,NULL), 7(134,'2019-07-01', 20,132,NULL), 8(135,'2019-10-01', 1000,135,NULL), 9(137,'2019-10-01', 1000,137,NULL), 10(138,'2019-10-01',-1000,137,NULL), 11(139,'2019-10-01', 1000,137,NULL), 12(140,'2019-10-01',-1000,137, 139), 13(141,'2019-11-01', 300,137, 139), 14(142,'2019-11-03', 700,137, 139), 15(143,'2019-11-03', -700,137, 142), 16(144,'2019-11-03', 300,137, 142), 17(145,'2019-11-10', 400,137, 142);

(1)134,135,145
(2)140,141,142,143,144,145
(3)139,142

で、(1)と(2)の集合から(3)を除いて
→134,135,140,141,143,144,145

内、140,143はamountがマイナスなので除いて
→134,135,141,144,145

ということですね?

SQL

1select * from tbl as t1 2inner join ( 3select max(id) as id from tbl group by tran_grp 4union select id from tbl where settle_grp is not null) as t2 using(id) 5where amount >= 0 6and not exists( 7select 1 from tbl 8where settle_grp is not null group by settle_grp having settle_grp = t2.id)

投稿2019/04/25 09:47

編集2019/04/25 09:50
yambejp

総合スコア114843

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

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

no1knows

2019/04/25 10:29

ありがとうございます。こちらで期待する回答を得ることができました! ベストアンサーは、最初に考え方などのヒントを教えてくれたmts10806さんにさせていただきます。
guest

0

#最終的にほしいレコードと質問の条件について合致しない部分があるので、#最終的にほしいレコードに合わせる形でSQLを組んでみました。
②select id from t_transactions where settle_grp IS not null;を含めると欲しい形にはなりません。

SQL

1select join1.* 2from t_transactions join1 3 inner join ( 4 select max(id) as id from t_transactions 5 where amount >= 0 6 group by tran_grp, payment_date 7 ) join2 8 on join1.id=join2.id

③の条件がIDに関するものというのに気付けなかった。
解決したようですけど、取り敢えず修正版です。

SQL

1select join1.* 2from t_transactions join1 3 inner join ( 4 select max(id) as id from t_transactions 5 where amount >= 0 6 group by tran_grp, payment_date 7 ) join2 8 on join1.id=join2.id 9where join1.id not in ( 10 select settle_grp from t_transactions where settle_grp IS NOT NULL 11 ) 12order by id

投稿2019/04/25 06:04

編集2019/04/25 10:58
sazi

総合スコア25195

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

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

no1knows

2019/04/25 06:25

ありがとうございます。 こちらを実行したところ残念ながらID139が残ってしまいました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問