
MySQLの自己結合を使って、3日間の売上データを同じ列に表示するプログラムを作っています。
日付が連続している場合(当日、1日前、2日前)のSQL文は作れたのですが、日付が飛んでいる(日付に抜けのある)場合のSQL文がうまく作れません。
どのようなSQL文を作成すればよいか教えていただければと思います。
テーブル名: sales2
カラム: id,product_id(製品コード),date(営業日),volume(売上)
----------------------------------------
3日間の売上データ(日付に抜けが無い場合)
----------------------------------------
SELECT A.id, A.product_id, A.date, A.volume, B.volume AS volumeB, C.volume AS volumeC
FROM sales2 AS A
INNER JOIN sales2 AS B ON A.product_id = B.product_id
AND A.date = DATE( B.date + INTERVAL 1 DAY )
INNER JOIN sales2 AS C ON A.product_id = C.product_id
AND A.date = DATE( C.date + INTERVAL 2 DAY )
ORDER BY A.product_id ASC , A.date DESC
+----+------------+------------+--------+---------+---------+
| id | product_id | date | volume | volumeB | volumeC |
+----+------------+------------+--------+---------+---------+
| 21 | 1 | 2017-01-10 | 57 | 12 | 88 |
| 20 | 1 | 2017-01-09 | 12 | 88 | 96 |
| 19 | 1 | 2017-01-08 | 88 | 96 | 28 |
| 18 | 1 | 2017-01-07 | 96 | 28 | 19 |
| 17 | 1 | 2017-01-06 | 28 | 19 | 70 |
| 27 | 1 | 2017-01-05 | 19 | 70 | 20 |
| 12 | 1 | 2017-01-04 | 70 | 20 | 30 |
| 11 | 1 | 2017-01-03 | 20 | 30 | 10 |
| 26 | 2 | 2017-01-10 | 60 | 90 | 29 |
| 25 | 2 | 2017-01-09 | 90 | 29 | 79 |
| 24 | 2 | 2017-01-08 | 29 | 79 | 26 |
| 23 | 2 | 2017-01-07 | 79 | 26 | 33 |
| 22 | 2 | 2017-01-06 | 26 | 33 | 64 |
| 28 | 2 | 2017-01-05 | 33 | 64 | 86 |
| 16 | 2 | 2017-01-04 | 64 | 86 | 30 |
| 15 | 2 | 2017-01-03 | 86 | 30 | 55 |
+----+------------+------------+--------+---------+---------+
16 rows in set (0.01 sec)
----------------------------------------
試してみたこと
----------------------------------------
volumeは当日の売上、volumeBは1日前の売上、volumeCは2日前の売上になっています。
DATE( C.date + INTERVAL 2 DAY ) の部分でサブクエリを使って当日より前の日付で最大のものを1つ抽出するようにすればよいと思い試しましたが、うまくいきませんでした。
----------------------------------
テストデータ
----------------------------------
CREATE TABLE IF NOT EXISTS `sales2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`volume` int(11) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=29 ;
INSERT INTO `sales2` (`id`, `product_id`, `volume`, `date`) VALUES
(9, 1, 10, '2017-01-01'),
(10, 1, 30, '2017-01-02'),
(11, 1, 20, '2017-01-03'),
(12, 1, 70, '2017-01-04'),
(13, 2, 55, '2017-01-01'),
(14, 2, 30, '2017-01-02'),
(15, 2, 86, '2017-01-03'),
(16, 2, 64, '2017-01-04'),
(17, 1, 28, '2017-01-06'),
(18, 1, 96, '2017-01-07'),
(19, 1, 88, '2017-01-08'),
(20, 1, 12, '2017-01-09'),
(21, 1, 57, '2017-01-10'),
(22, 2, 26, '2017-01-06'),
(23, 2, 79, '2017-01-07'),
(24, 2, 29, '2017-01-08'),
(25, 2, 90, '2017-01-09'),
(26, 2, 60, '2017-01-10'),
(27, 1, 19, '2017-01-05'),
(28, 2, 33, '2017-01-05');
No.2ベストアンサー
- 回答日時:
調整しました
select
t4.id,t4.product_id,t4.date,t4.volume,t5.volume as volume2,t6.volume as volume3
from (
select t1.id,t1.product_id,t1.volume,t1.date
,(select max(t2.date) from `sales2` as t2 where t1.date>t2.date and t1.product_id=t2.product_id) as t2_date
,(select max(t3.date) from `sales2` as t3 where t2_date>t3.date and t1.product_id=t3.product_id) as t3_date
from `sales2` as t1
having t3_date is not null
) as t4
inner join `sales2` as t5
on t5.date=t2_date
and t4.product_id=t5.product_id
inner join `sales2` as t6
on t6.date=t3_date
and t4.product_id=t6.product_id
order by t4.product_id asc,t4.date desc
yambejp様
ご回答ありがとうございました。求める結果を得ることができました。
このような集計は現在作っているプログラムで多用することになるので、本当に助かりました。
今後とも宜しくお願い致します。
No.1
- 回答日時:
SELECT * FROM `sales2` as t1
inner join `sales2` as t2
on t1.date=t2.date + interval 1 day
and t1.product_id=t2.product_id
inner join `sales2` as t3
on t1.date=t3.date + interval 2 day
and t1.product_id=t3.product_id
order by t1.product_id asc, t1.date desc
yambejp 様
ご回答ありがとうございます。
ご提示のSQL文で、日付が無い日のデータが含まれる場合、データが表示されないことが確認できました。
わたくしの質問がうまく書けていなかったようです。お手数かけて申し訳ありません。求めている結果は以下のようなものになります。
「データ」
2017-01-01
2017-01-02
2017-01-03
2017-01-04
2017-01-05
2017-01-06
[2017-01-07が無い]
2017-01-08
2019-01-09
2017-01-10
「求める出力」
2017-01-10 2019-01-09 2017-01-08
2017-01-09 2019-01-08 2017-01-06 ※1
2017-01-08 2019-01-06 2017-01-05 ※2
2017-01-06 2019-01-05 2017-01-04
:::
2017-01-07が無いので、その場合はその前の日のデータを取得する。
元のデータは連続して2日抜けていたり、3日抜けていたり、1日おきにデータが抜けていたりします。(土日、休祝日のデータが無いような形です)
大変お手数をお掛けいたしますが、再度ご回答頂ければと思います。宜しくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL MYSQL エラー 2 2022/10/18 11:37
- MySQL my_itemsテーブルのIDにAUTO_INCREMENT を追加ができるかで 1 2023/01/03 09:09
- PHP php エラー 2 2022/10/23 16:43
- MySQL `picture` varchar(255) のコマンドで間違いないでしょうか? 1 2022/11/21 04:08
- MySQL 2つのカラムでgroup by の動作をさせるSQLの構文を教えてください。 3 2022/05/19 19:02
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- Excel(エクセル) マクロで行を追加、削除すると行位置がずれますが、解決方法はありませんか?。 5 2022/05/28 16:03
- JavaScript gasについて 1 2022/05/31 21:51
- Access(アクセス) ExcelのVBAコードについて教えてください。 4 2023/01/20 09:44
- MySQL 次の時間帯の勝率の合計を求めるSQL文 1 2023/07/04 17:12
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
selectした大量データをinsert...
-
select文のwhere句に配列を入れ...
-
SQL Left Join で重複を排除す...
-
ある条件の最大値+1を初番する...
-
[MySQL] 3つのテーブルの結合で...
-
updateを1行ずつ実行したい。
-
エラー 1068 (42000): 複数の主...
-
マイクラPC版のコマンドで効率...
-
WordpressのContact form 7でzi...
-
Postgreのupdateコマンドでエラー
-
ポニョの替え歌のポーニョポニ...
-
複数テーブルのGROUP BY の使い...
-
テーブルのフィールド名の命名...
-
連動させて表示させる方法
-
sqlで、600行あるテーブルを100...
-
【Transact-sql】 execの結果を...
-
【初心者】特定の文字に色をつ...
-
MYSQLのクエリの最適化について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
sqlで、600行あるテーブルを100...
-
select文のwhere句に配列を入れ...
-
SQLにて特定の文字を除いた検索...
-
WordpressのContact form 7でzi...
-
SQLサーバから、項目の属性(型...
-
VIEWの元のテーブルのindexって...
-
クエリ表示と、ADOで抽出したレ...
-
マイクラPC版のコマンドで効率...
-
【Transact-sql】 execの結果を...
-
SQL Left Join で重複を排除す...
-
エラー 1068 (42000): 複数の主...
-
[MySQL] UNIQUE制約の値を更新...
-
inner joinをすると数がおかし...
-
1テーブル&複数レコードの更新...
-
Access パラメータクエリをcsv...
-
期間の重複を調べるSQL文につい...
-
Unionした最後にGROUP BYを追加...
-
Updateの複数テーブル条件時のL...
おすすめ情報