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

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

解決済

1回答

6217閲覧

サブクエリを使わない書き方

hasepu0

総合スコア12

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/01/27 10:43

商品(item)

idnamecost
1りんご100
2みかん70
3バナナ200
4メロン1000

仕入れ(purchase)

iditem_idcount
1110
241
326
415
538

売上(sales)

iditem_idcount
123
214
316
436

というデータベースがあるとして
仕入れた商品から売上で減った分の現在の在庫の合計価格を求めたいのですが
これをサブクエリなしでTEMPORARY TABLEを使って書く方法が知りたいです。

自分で考えて書いたところこんな感じになってしまったのですが
もっとスマートな書き方があるのではないかと思い質問させていただきました。

SQL

1create temporary table tmp1( 2 select purchase.item_id, sum(purchase.count) * item.cost costs 3 from purchase, item 4 where item.id = purchase.item_id 5 group by purchase.item_id 6); 7 8create temporary table tmp2( 9 select sales.item_id, sum(sales.count) * item.cost costs 10 from sales 11, item 12 where item.id = sales.item_id 13 group by sales.item_id 14); 15 16select sum(tmp1.costs) - sum(tmp2.costs) 17 from tmp1 18 left join tmp2 19 on tmp1.item_id = tmp2.item_id; 20

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

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

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

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

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

guest

回答1

0

ベストアンサー

一時テーブルを使用するのは速度面での対応ですか?
そうであるなら、インデックスさえ適切ならサブクエリーでも問題ないと思います。
逆に一時テーブルでもインデックス使用しないと意味が無かったりしますので。

SQL

1select item.* 2 , cost * (coalesce(item_purchase.cnt, 0) - coalesce(item_sales.cnt, 0)) 3from item left join ( 4 select item_id, sum(`count`) as cnt from purchase group by item_id 5 ) as item_purchase 6 on item.id = item_purchase.item_id 7 left join ( 8 select item_id, sum(`count`) as cnt from sales group by item_id 9 ) as item_sales 10 on item.id = item_sales.item_id

または

SQL

1select * 2 , cost * ( 3 coalesce((select sum(`count`) from purchase where item_id=item.id), 0) 4 - coalesce((select sum(`count`) from sales where item_id=item.id), 0) 5 ) 6from item

投稿2019/01/27 12:33

sazi

総合スコア25173

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

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

hasepu0

2019/01/27 13:56

回答ありがとうございます。 まだSQLは学習し始めたばかりで、速度面を気にする段階でもないのですが とある規約でサブクエリが禁止されていまして、どう書くのが適切なのかと思い質問いたしました。 ただ、coalesceという関数も知らなかったので、こういう書き方もできるのかととても参考になります。
sazi

2019/01/27 14:30 編集

1番目のSQLではインラインビューですけど、サブクエリーの対象なら、その部分を一時テーブルとして下さい。 規約については目的があるはずですから、確認した方がいいですよ。 一般的にMYSQLではサブクエリーが遅いとされています。 なので、それが理由ではないかと思います。
hasepu0

2019/01/27 23:22

納得いたしました。詳しく教えていただいてありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問