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

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

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

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

SQL

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

Q&A

解決済

2回答

6277閲覧

SQL文で4つのテーブルから参照して、カラムの合計値を重複せずに出したい

THitokuse

総合スコア49

MySQL

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

SQL

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

0グッド

1クリップ

投稿2019/02/25 04:00

行いたいこと

現在、4つのテーブルを参照してその中のカラムの合計値を出したいのですが、明らかに値が大きくなってしまいます。
調べたところ、inner joinを行うとテーブルのレコード数が重複してしまい、重複した値もsumに取り入れられてしまいます。

現状、inner joinの一つを from句の中に入れて1つのテーブルからの重複は免れたのですが、残り2つのテーブルが重複してしまいます。
回答わかる方いらっしゃいますでしょうか?

テーブルとカラム

  • usersテーブル
idname...
1test...
2aaaa...
3bbbb...
...
  • appsテーブル
iduser_idname...
12app_test...
22cccc...
32dddd...
...
  • ▲▲テーブル
idapp_id...
13...
21...
32...
...
  • ××テーブル
idapp_id...
12...
21...
33...
...
  • 出したい値

→ 同じuserが作成したappsの▲▲テーブルと××テーブルに紐づいた合計
ex:
aaaa(user_id:2)が作成したapp(ここでは、app_id:[1,2,3])に紐づく▲▲テーブルと××テーブルのカラム集計(sum)

試したこと

SQL文(from句内にselect文を作成)

select ( sum(▲▲.カラム名1), sum(▲▲.カラム名2), sum(××.カラム名), count(apps.id) ) from (select id, user_id, count(apps.id) from apps where user_id = 2) as apps inner join inner join users on apps.user_id = users.id inner join ▲▲ on apps.id = ▲▲.app_id inner join ×× on apps.id = ××.app_id;

sumの中が期待される値よりも大きくなってしまう。

SQL文(カラムごとにdistinct生成)

select ( sum(distinct ▲▲.カラム名1), sum(distinct ▲▲.カラム名2), sum(distinct ××.カラム名), count(apps.id) ) from (select id, user_id, count(apps.id) from apps where user_id = 2) as apps inner join inner join users on apps.user_id = users.id inner join ▲▲ on apps.id = ▲▲.app_id inner join ×× on apps.id = ××.app_id;

sumの中が期待される値よりも小さくなってしまう。

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

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

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

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

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

guest

回答2

0

ベストアンサー

全部をINNER JOINすると▲▲と××かけ合わせたレコードが出てくるので、大きくなると思いますし、
DISTINCTは▲▲と××でそれぞれのテーブル内で重複をカットするので意味が違います。

いくつか解決策はありますが、こういうときは段階を追って実現すると良いと思います。

まずは▲▲テーブルでユーザごとの合計を出してみます。
※求めたいカラム名を便宜的にXとYとしました。

SQL

1SELECT apps.user_id, SUM(▲▲.X), SUM(▲▲.Y) 2FROM apps 3INNER JOIN ▲▲ ON apps.id = ▲▲.id 4GROUP BY user_id;

これでユーザIDごとの合計値が出ると思います。
××テーブルでも同様にします。

SQL

1SELECT apps.user_id, SUM(××.Z) 2FROM apps 3INNER JOIN ×× ON apps.id = ××.id 4GROUP BY user_id;

上の2つを副問合せでsum1、sum2にして、usersテーブルと結合すれば求めたい情報になるかと思います。

SQL

1SELECT users.id, users.name, sum1.x, sum1.y, sum2.z 2FROM users 3INNER JOIN 4( 5 SELECT apps.user_id, SUM(▲▲.X) as x, SUM(▲▲.Y) as y 6 FROM apps 7 INNER JOIN ▲▲ ON apps.id = ▲▲.id 8 GROUP BY user_id 9) as sum1 10ON users.id = sum1.user_id 11INNER JOIN 12( 13 SELECT apps.user_id, SUM(××.Z) as z 14 FROM apps 15 INNER JOIN ×× ON apps.id = ××.id 16 GROUP BY user_id 17) as sum2 18ON users.id = sum2.user_id 19ORDER BY users.id;

投稿2019/02/25 04:22

mackerel6.023

総合スコア317

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

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

THitokuse

2019/02/25 10:07

INNER JOINの中でselect文作成できることlは知らなかったので勉強になりました。 そちらの方法で期待していた値が取れました。 ありがとうございます!!
guest

0

appsのidを限定した集計にするという事が目的の場合の原因は、apps のuser_id毎に取得するIDが1件になっていない事です。
下記はMax()を取得しています。

SQL

1select user_id, max(id) as id, count(id) as cnt 2from apps 3where user_id = 2

上記のように、IDを限定した上で結合すれば求める結果になるかと思います。

また、user_id毎にappsに関連したデータの集計という場合は、以下の様になります。

SQL

1select user_id 2 , sum(▲▲.カラム名1) 3 , sum(▲▲.カラム名2) 4 , sum(××.カラム名) 5 , count(distinct apps.id) 6from apps 7 inner join ▲▲ 8 on apps.id = ▲▲.app_id 9 inner join ×× 10 on apps.id = ××.app_id 11where apps.user_id = 2 12group by apps.user_id

投稿2019/02/25 04:18

編集2019/02/25 04:49
sazi

総合スコア25138

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

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

THitokuse

2019/02/25 10:09

回答ありがとうございます! IDを限定して出力した後さらにINNER JOIN内でselect文を回す必要があったみたいです! 解決しました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問