MySQLの質問です。最初にSQL文を教えてくださった方には300ポイントさしあげます。困っています。どうぞよろしくお願いします。m(。。)m


(日付) (商品名) (数量)
2010-08-01 消しゴム 14
2010-08-01 えんぴつ 13
2010-08-01 定規 1
2010-08-02 消しゴム 5
2010-08-02 えんぴつ 10
2010-08-02 定規 3
2010-08-03 消しゴム 4
2010-08-03 えんぴつ 6
2010-08-03 定規 8

というテーブルから、以下のような出力を得たいのですが、
どのようにselect文をかけばよいのでしょうか?

        消しゴム えんぴつ 定規
2010-08-01 14 13 1
2010-08-02 5 10 3
2010-08-03 4 6 8

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2010/08/17 15:03:46
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149

ポイント300pt

【1】集計は必須

>日付x商品はkeyになっているので、1つの日付x商品の組み合わせに対しては1つのレコードしかありません。

>ですので、sumは使わなくても大丈夫だと思います。。

 

INSERTはUNIQUE判定を行いますが、

SELECTにおいてはUNIQUE判定は行われないためsumは必要な措置となります

 

【2】一度にはできない。一度に行う必要も無い

>商品名は1000以上あるので、それぞれを入力していくわけにはいかない

 

当然でてくるだろうと想定しておくべき事柄ですね

残念ながらMySQLにはPIVOT/クロス集計機能は無く回答1の手段を用いることになります

 

【3】対処

(例1)回答1のSQLを参考に、phpなどで、その場その時に必要なフィールドだけに絞ったSQLを生成して発行

フィールド名が都度変わるため処理は煩雑で面倒

 

(例2)縦一列の形で集計したものをphp側で横一列として画面出力や印刷を行う

日付x商品はkeyになっているので集計の必要も無く、

phpなどで先頭から1レコードずつ読み出して横に書き並べ、日付が変わったら改行するだけで簡単です

SELECT *
FROM テーブル名
WHERE (日付 BETWEEN '2010-08-01' AND '2010-08-03') AND (商品コード BETWEEN 100 AND 150);

過去の質問を閲覧しても利用言語環境が分からないので、ひとまずここまでにしておきます

 

参考URLはいまのところありません

http://q.hatena.ne.jp/answer

id:norix31

windofjulyさん、丁寧な回答ありがとうございます。

 

>残念ながらMySQLにはPIVOT/クロス集計機能は無く回答1の手段を用いることになります

 

これが知りたかったことの核心でした!

 

それで、対処の[2]でなんとかなりそうです。

考えるヒントもたくさんいただけたので、これをもとに少し考えてみます。

どうもありがとうございました。

2010/08/17 15:02:59

その他の回答1件)

id:khazad-Lefty No.1

回答回数181ベストアンサー獲得回数27

ポイント300pt

Case文

http://dev.mysql.com/doc/refman/5.1/ja/control-flow-functions.ht...

を使うといいと思います。


select 
日付,
Sum(Case When 商品名='消しゴム' then 数量 else 0 end) as 消しゴム
Sum(Case When 商品名='えんぴつ' then 数量 else 0 end) as 消しゴム
Sum(Case When 商品名='定規' then 数量 else 0 end) as 消しゴム
group by 日付


id:norix31

khazad-Leftyさん、ご回答ありがとうございます。

それで、すみません。説明がわかりづらかったです。

日付x商品はkeyになっているので、1つの日付x商品の組み合わせに対しては1つのレコードしかありません。

ですので、sumは使わなくても大丈夫だと思います。。

それと、商品名は1000以上あるので、それぞれを入力していくわけにはいかないのです。

以上をふまえて、どうすればいいでしょうか?

引き続き回答を募集しています。

よろしくお願いします。m(。。)m

2010/08/17 13:51:05
id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149ここでベストアンサー

ポイント300pt

【1】集計は必須

>日付x商品はkeyになっているので、1つの日付x商品の組み合わせに対しては1つのレコードしかありません。

>ですので、sumは使わなくても大丈夫だと思います。。

 

INSERTはUNIQUE判定を行いますが、

SELECTにおいてはUNIQUE判定は行われないためsumは必要な措置となります

 

【2】一度にはできない。一度に行う必要も無い

>商品名は1000以上あるので、それぞれを入力していくわけにはいかない

 

当然でてくるだろうと想定しておくべき事柄ですね

残念ながらMySQLにはPIVOT/クロス集計機能は無く回答1の手段を用いることになります

 

【3】対処

(例1)回答1のSQLを参考に、phpなどで、その場その時に必要なフィールドだけに絞ったSQLを生成して発行

フィールド名が都度変わるため処理は煩雑で面倒

 

(例2)縦一列の形で集計したものをphp側で横一列として画面出力や印刷を行う

日付x商品はkeyになっているので集計の必要も無く、

phpなどで先頭から1レコードずつ読み出して横に書き並べ、日付が変わったら改行するだけで簡単です

SELECT *
FROM テーブル名
WHERE (日付 BETWEEN '2010-08-01' AND '2010-08-03') AND (商品コード BETWEEN 100 AND 150);

過去の質問を閲覧しても利用言語環境が分からないので、ひとまずここまでにしておきます

 

参考URLはいまのところありません

http://q.hatena.ne.jp/answer

id:norix31

windofjulyさん、丁寧な回答ありがとうございます。

 

>残念ながらMySQLにはPIVOT/クロス集計機能は無く回答1の手段を用いることになります

 

これが知りたかったことの核心でした!

 

それで、対処の[2]でなんとかなりそうです。

考えるヒントもたくさんいただけたので、これをもとに少し考えてみます。

どうもありがとうございました。

2010/08/17 15:02:59

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません