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

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

新規登録して質問してみよう
ただいま回答率
85.49%
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回答

2404閲覧

商品別・月別販売金額とその推移を出したい

yyy

総合スコア49

MySQL

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

SQL

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

2グッド

1クリップ

投稿2016/02/10 08:34

編集2016/02/10 13:01

###前提・実現したいこと
2007年06月~08月までの商品ごとの販売金額を抽出し、更に前月からの増減を↑・→・↓で表示させる表を作りたい。
以下、増減以外を求めた表です。

MySQL

1SELECT 2 B.ProductID 3 ,D.ProductName 4 ,SUM(CASE WHEN B.年月 = '2007-06' THEN B.Price*B.Quantity ELSE 0 END) AS "6月販売金額" 5 ,SUM(CASE WHEN B.年月 = '2007-07' THEN B.Price*B.Quantity ELSE 0 END) AS "7月販売金額" 6 ,SUM(CASE WHEN B.年月 = '2007-08' THEN B.Price*B.Quantity ELSE 0 END) AS "8月販売金額" 7 FROM 8 ( 9 SELECT 10 C.ProductID 11 ,A.Quantity 12 ,C.Price 13 ,SUBSTR(A.SaleDate, 1, 7) AS 年月 14 FROM 15 Sales AS A 16 INNER JOIN 17 Products AS C 18 ON A.ProductID = C.ProductID 19 WHERE 20 A.SaleDate BETWEEN '2007-06-01' AND '2007-08-31' 21 GROUP BY 22 C.ProductID 23 ,A.Quantity 24 ,C.Price 25 ,A.SaleDate 26 ) AS B 27 INNER JOIN 28 Products AS D 29 ON B.ProductID = D.ProductID 30GROUP BY 31 B.ProductID 32ORDER BY 33 B.ProductID 34;

###発生している問題・エラーメッセージ
一番下のサブクエリが働いていないようなのですが、JOINの仕方が間違っているのでしょうか?

###ソースコード

MySQL

1SELECT 2 P.ProductID 3 ,P.ProductName 4 ,E."6月販売金額" 5 ,E."7月販売金額" 6 ,CASE WHEN E."6月販売金額" > E."7月販売金額" THEN '↓' 7 WHEN E."6月販売金額" = E."7月販売金額" THEN '→' 8 ELSE '↑' END AS "対6月増減" 9 ,E."8月販売金額" 10 ,CASE WHEN E."7月販売金額" > E."8月販売金額" THEN '↓' 11 WHEN E."7月販売金額" = E."8月販売金額" THEN '→' 12 ELSE '↑' END AS "対7月増減" 13 FROM 14 ( 15 SELECT 16 W.ProductID 17 ,SUBSTR(Q.SaleDate, 1, 7) AS 年月 18 FROM 19 Sales AS Q 20 INNER JOIN 21 Products AS W 22 WHERE 23 Q.SaleDate BETWEEN '2007-06-01' AND '2007-08-31' 24 ) AS B 25 INNER JOIN 26 Products AS P 27 ON B.ProductID = P.ProductID 28 INNER JOIN 29 ( 30 SELECT 31 D.ProductID 32 ,SUM(CASE WHEN B.年月 = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額" 33 ,SUM(CASE WHEN B.年月 = '2007-07' THEN D.Price*C.Quantity ELSE 0 END) AS "7月販売金額" 34 ,SUM(CASE WHEN B.年月 = '2007-08' THEN D.Price*C.Quantity ELSE 0 END) AS "8月販売金額" 35 FROM 36 Sales AS C 37 INNER JOIN 38 Products AS D 39 ON C.ProductID = D.ProductID 40 GROUP BY 41 D.ProductID 42 ) AS E 43 ON P.ProductID = E.ProductID 44ORDER BY 45 P.ProductID 46;

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

出力項目:ProductID、ProductName、6月販売金額、7月販売金額、対6月増減、8月販売金額、対7月増減
出力順:ProductID

mhashi, yodel👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

またまたお邪魔します。
テーブルEのサブクエリ内で、B.年月は存在してないかと思います。

投稿2016/02/10 08:42

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

yyy

2016/02/12 06:23 編集

Eのサブクエリより先にBのサブクエリが働いているとは限らないということですね…。 どうしてもこの形にしたいわけではないのですが、これがきれいなように見えてしまって…。
退会済みユーザー

退会済みユーザー

2016/02/12 00:11

こんにちは。 Eのサブクエリ内のSUMの3箇所を以下のようにしてみてはいかかでしょう。 【変更前】 SUM(CASE WHEN B.年月 = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額" 【変更後】 SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額" 試してみてください。 よろしくお願いします。
yyy

2016/02/12 02:19

【変更後】に書いていただいたもので試してみたところ、not foundのエラーが出なくなりました。先に年月を抽出して繋ぐ必要なんてなかったんですね…。変なところにこだわってしまっていたようです。 まだ必要な行が出ていなかったりするので、もう少し弄ってみます。 ありがとうございます。
yyy

2016/02/12 06:06 編集

度々すみません。以下のように直してみたのですが、これだと6月から8月に販売履歴のないものの行が抜け落ちてしまいます。(SaleDateがNULLということだと思います。) SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額"の部分に WHEN SUBSTR(C.SaleDate, 1, 7) IS NULL THEN 0 ELSE 0 を付け足してみたのですが、0表記だったものがすべてNULLになりました…。 これってどこでNULLを0で表示するという指示を出さないといけないのでしょうか? SELECT P.ProductID ,P.ProductName ,E."6月販売金額" ,E."7月販売金額" ,CASE WHEN E."6月販売金額" > E."7月販売金額" THEN '↓' WHEN E."6月販売金額" = E."7月販売金額" THEN '→' ELSE '↑' END AS "対6月増減" ,E."8月販売金額" ,CASE WHEN E."7月販売金額" > E."8月販売金額" THEN '↓' WHEN E."7月販売金額" = E."8月販売金額" THEN '→' ELSE '↑' END AS "対7月増減" FROM Products AS P LEFT OUTER JOIN ( SELECT D.ProductID ,SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額" ,SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-07' THEN D.Price*C.Quantity ELSE 0 END) AS "7月販売金額" ,SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-08' THEN D.Price*C.Quantity ELSE 0 END) AS "8月販売金額" FROM Sales AS C INNER JOIN Products AS D ON C.ProductID = D.ProductID WHERE C.SaleDate BETWEEN '2007-06-01' AND '2007-08-31' GROUP BY D.ProductID ) AS E ON P.ProductID = E.ProductID ORDER BY P.ProductID ;
退会済みユーザー

退会済みユーザー

2016/02/12 06:51

こんにちは。 NULLを 0 にしたいのであれば以下のような形でどうでしょうか。 ---------- ↓ ここから ↓ ---------- SELECT P.ProductID , P.ProductName , IFNULL(E.`6月販売金額`,0) , IFNULL(E.`7月販売金額`,0) , CASE WHEN IFNULL(E.`6月販売金額`,0) > IFNULL(E.`7月販売金額`,0) THEN '↓' WHEN IFNULL(E.`6月販売金額`,0) = IFNULL(E.`7月販売金額`,0) THEN '→' ELSE '↑' END AS "対6月増減" , IFNULL(E.`8月販売金額`,0) , CASE WHEN IFNULL(E.`7月販売金額`,0) > IFNULL(E.`8月販売金額`,0) THEN '↓' WHEN IFNULL(E.`7月販売金額`,0) = IFNULL(E.`8月販売金額`,0) THEN '→' ELSE '↑' END AS "対7月増減" FROM Products AS P LEFT OUTER JOIN ( SELECT D.ProductID , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS "6月販売金額" , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-07' THEN D.Price*C.Quantity ELSE 0 END) AS "7月販売金額" , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-08' THEN D.Price*C.Quantity ELSE 0 END) AS "8月販売金額" FROM Sales AS C INNER JOIN Products AS D ON C.ProductID = D.ProductID WHERE C.SaleDate BETWEEN '2007-06-01' AND '2007-08-31' GROUP BY D.ProductID ) AS E ON P.ProductID = E.ProductID ORDER BY P.ProductID; --------- ↑ ここまで ↑ ---------- 確認してみてください。
yyy

2016/02/12 07:41 編集

ありがとうございます。 試してみたのですが、エラーになってしまいました。 それを受けて、条件を入れる順番を変えてみたら、販売履歴がない商品が3つだったのにそのうちの1つだけがなぜか表示されるようになりました…。不思議でたまりません…。 SELECT P.ProductID ,P.ProductName ,E."6月販売金額" ,E."7月販売金額" ,CASE WHEN E."6月販売金額" > E."7月販売金額" THEN '↓' WHEN E."6月販売金額" = E."7月販売金額" THEN '→' ELSE '↑' END AS "対6月増減" ,E."8月販売金額" ,CASE WHEN E."7月販売金額" > E."8月販売金額" THEN '↓' WHEN E."7月販売金額" = E."8月販売金額" THEN '→' ELSE '↑' END AS "対7月増減" FROM Products AS P LEFT OUTER JOIN ( SELECT D.ProductID ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END ) AS "6月販売金額" ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-07' THEN D.Price*C.Quantity ELSE 0 END ) AS "7月販売金額" ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-08' THEN D.Price*C.Quantity ELSE 0 END ) AS "8月販売金額" FROM Sales AS C INNER JOIN Products AS D ON C.ProductID = D.ProductID GROUP BY D.ProductID ) AS E ON P.ProductID = E.ProductID ORDER BY P.ProductID ;
退会済みユーザー

退会済みユーザー

2016/02/12 07:49

こんにちは。 もしよろしければ、 エラーの内容を張って頂けますでしょうか。 宜しくお願い致します。
yyy

2016/02/12 08:08

すみません、エラーというか欲しい値が出ないという意味でした。 ・IFNULL(E.`6月販売金額`,0)がそのまま列名で出てくる  →これはASで別名を付ければ大丈夫ですよね ・対6月増減、対7月増減がNULL(ブランク)状態になる ◎*月販売金額のNULL表示を0に変換したい →これはできていました! 言葉が足りな過ぎでした。何度も申し訳ないです…。
退会済みユーザー

退会済みユーザー

2016/02/12 08:37 編集

こんにちは。 >・対6月増減、対7月増減がNULL(ブランク)状態になる この現象が再現できません。 今、私が適当に作ったデータは以下です。 【Products】 ProductID,ProductName,Price 0001,プロダクト1,100 0002,プロダクト2,200 0003,プロダクト3,300 【Sales】 0001,10,2007-06-02 0001,15,2007-07-02 0002,10,2007-07-08 0002,30,2007-08-19 0001,5,2007-08-26 0002,50,2007-06-09 0001,2,2007-06-03 【SQL】 SELECT P.ProductID , P.ProductName , IFNULL(E.`6月販売金額`,0) AS '6月販売金額' , IFNULL(E.`7月販売金額`,0) AS '7月販売金額' , CASE WHEN IFNULL(E.`6月販売金額`,0) > IFNULL(E.`7月販売金額`,0) THEN '↓' WHEN IFNULL(E.`6月販売金額`,0) = IFNULL(E.`7月販売金額`,0) THEN '→' ELSE '↑' END AS '対6月増減' , IFNULL(E.`8月販売金額`,0) AS '8月販売金額' , CASE WHEN IFNULL(E.`7月販売金額`,0) > IFNULL(E.`8月販売金額`,0) THEN '↓' WHEN IFNULL(E.`7月販売金額`,0) = IFNULL(E.`8月販売金額`,0) THEN '→' ELSE '↑' END AS '対7月増減' FROM Products AS P LEFT OUTER JOIN ( SELECT D.ProductID , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END) AS '6月販売金額' , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-07' THEN D.Price*C.Quantity ELSE 0 END) AS '7月販売金額' , SUM(CASE WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-08' THEN D.Price*C.Quantity ELSE 0 END) AS '8月販売金額' FROM Sales AS C INNER JOIN Products AS D ON C.ProductID = D.ProductID WHERE C.SaleDate BETWEEN '2007-06-01' AND '2007-08-31' GROUP BY D.ProductID ) AS E ON P.ProductID = E.ProductID ORDER BY P.ProductID; 【結果】 ProductID,ProductName,6月販売金額,7月販売金額,対6月増減,8月販売金額,対7月増減 0001,プロダクト1,1200,0,↓,500,↑ 0002,プロダクト2,10000,2000,↓,6000,↑ 0003,プロダクト3,0 ,0,→,0,→ この状況で何か認識が違うものはありますでしょうか。 ご指摘頂けたら幸いです。 よろしくお願い致します。
yyy

2016/02/15 00:38

わざわざすみません。ありがとうございます。 結果として間違ったところはありません。その形が私が出したかったものです。 Shindo_NJSさんが書いてくださったコードをそのままコピペして使わせていただいたので、なぜこちらのみできないのか不明ですが…。環境等異なるのでしょうかね。
退会済みユーザー

退会済みユーザー

2016/02/15 00:49

おはようございます。 認識の違いがなく安心しました。 MySQLのバージョンを教えていただけますでしょうか。 当方、ver.5.5を使用しております。
yyy

2016/02/15 01:45

大変申し訳ありませんが、学習用CD-ROMを使用しているためバージョン等わかりかねます。
退会済みユーザー

退会済みユーザー

2016/02/15 02:49 編集

こんにちは。 一応、同じバージョンで確認しようと思っただけですのでお気になさらず。 バージョンで左右されるようなSQLでもない気がしますので。 現状の問題点としては、 >・対6月増減、対7月増減がNULL(ブランク)状態になる だけでしょうか。 この箇所がNULLになる原因は比較式のいずれかがNULLである場合ですが、 >◎*月販売金額のNULL表示を0に変換したい >→これはできていました! IFNULLは機能しているため、NULL対応も問題ないはずです。 CASE文を分解してみて比較式を確認してみてはいかがでしょうか。 【分解後】 ,CASE WHEN IFNULL(E.`6月販売金額`,0) < IFNULL(E.`7月販売金額`,0) THEN '○' ELSE '×' END AS '対6月増減↑' ,CASE WHEN IFNULL(E.`6月販売金額`,0) > IFNULL(E.`7月販売金額`,0) THEN '○' ELSE '×' END AS '対6月増減↓' ,CASE WHEN IFNULL(E.`6月販売金額`,0) = IFNULL(E.`7月販売金額`,0) THEN '○' ELSE '×' END AS '対6月増減→' 原因は他にもあるかもしれませんが、 ひとつひとつ見つけていくしかなさそうですね。 お力になれず申し訳ございません。 よろしくお願い致します。
yyy

2016/02/15 05:41

何故正しく表示されなかったのかわかりました! どうやらサブクエリの中のJOIN FROM    Sales AS C INNER JOIN     Products AS D ON C.ProductID = D.ProductID の部分が、Productsテーブルを主にしたLEFT OUTER JOINでないとダメだったようです。(本当にしょうもないことでした…。)お時間を割いていただいてありがとうございました。 また、まだまだ勉強不足の為IFNULLの使い方がいまいちわからず、結局以下のような形にしました。 SELECT P.ProductID ,P.ProductName ,E."6月販売金額" ,E."7月販売金額" ,CASE WHEN E."6月販売金額" > E."7月販売金額" THEN '↓' WHEN E."6月販売金額" = E."7月販売金額" THEN '→' ELSE '↑' END AS "対6月増減" ,E."8月販売金額" ,CASE WHEN E."7月販売金額" > E."8月販売金額" THEN '↓' WHEN E."7月販売金額" = E."8月販売金額" THEN '→' ELSE '↑' END AS "対7月増減" FROM Products AS P INNER JOIN ( SELECT D.ProductID ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-06' THEN D.Price*C.Quantity ELSE 0 END ) AS "6月販売金額" ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-07' THEN D.Price*C.Quantity ELSE 0 END ) AS "7月販売金額" ,SUM(CASE WHEN C.Quantity IS NULL THEN 0 WHEN SUBSTR(C.SaleDate, 1, 7) = '2007-08' THEN D.Price*C.Quantity ELSE 0 END ) AS "8月販売金額" FROM Products AS D LEFT OUTER JOIN Sales AS C ON C.ProductID = D.ProductID GROUP BY D.ProductID ) AS E ON P.ProductID = E.ProductID ORDER BY P.ProductID ; お陰様で完成いたしました。色々とありがとうございました。
退会済みユーザー

退会済みユーザー

2016/02/15 05:48

こんにちは。 自己解決はスッキリしますよね。 おめでとうございます。
date

2016/02/15 06:08

終わった後でいうのはなんですが、これyyyさんの最後の答えは普通に1064エラーになりませんか? バージョンでならないというなら私の勉強不足ですが
yyy

2016/02/15 06:15

自分のところで問題なく必要レコードが抽出されたので上記コードを載せています。 他のバージョンだとどこかおかしなところあるのでしょうか。
退会済みユーザー

退会済みユーザー

2016/02/15 06:38

こんにちは。 おそらくdateさんは、ここのソースをそのまま実行した可能性があります。 E."6月販売金額"のようなカラムの場合、 "(ダブルクォーテーション)でなく、 `(バッククォーテーション)となるはずですので、 変換すればエラーは解消されませんか? お試しください。
yyy

2016/02/15 07:08

皆さん仰っているようにシングルが正しいのでしょうけれど、 私のところでは数字の含まれるテーブル名の場合、ダブルにしないとエラーが返ってきてしまうのでそのままコードを載せてしまいました・・。
date

2016/02/15 09:36

'(シングルクォーテーション)と ```ここに言語を入力 `(バッククォーテーション) ````は別です。 (バッククォーテーション)はテーブル名やカラム名などを囲むときに使用します。 AS '6月販売金額'は エラーになりませんが、E."7月販売金額"の部分はエラーになるはずです。mysql5.6にて確認はしました。  ダブルクォーテーションでエラーにならないなら、すいませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問