• 締切済み

効率の良いSQL文の書き方を教えてください

MySQLで開発をしています。 1回のSQLで、下記テーブルの内容を日付・ユーザ番号毎(日付・ユーザ番号が同じ時に同じレコード)に、 型番1個数、 型番2個数、 その他が2か3で型番2・品番1個数、 その他が2か3で型番2・品番1個数、 その他が2か3で型番2・品番1での売上小計、 その他が2か3で型番2・品番2個数での売上小計、 売上合計、 以上の各カラムを持つテーブルに再編して返したいのですが、 効率の良いやり方がわかりません。 どなたかよろしくお願いします。 テーブル ユーザ番号 日付   型番  品番   売上  その他 ----- --- --- --- --- ---  001     3/10    1    2     500    1  001     3/10    2    1      0    1  003     3/11    2    1     100    2  004     3/12    1    1     100    2  005     3/12    2    2      0     2  001     3/13    1    2     500    1  003     3/13    2    1     100    2  003     3/13    2    1      0     3  002     3/14    1    1     100    3  005     3/15    2    2     0      1

  • MySQL
  • 回答数2
  • ありがとう数2

みんなの回答

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.2

CASE文で条件ごとに集計すればいいのではないでしょうか? 一部あやふやな項目があったので雰囲気だけでも。 select ユーザ番号,日付 ,count(case when 型番 = 1 then 1 else null end) 型番1個数 ,count(case when 型番 = 2 then 1 else null end) 型番2個数 ,count(case when その他 in (2,3) and 型番 = 2 and 品番 = 1 then 1 else null end) 型番2品番1個数 ,count(case when その他 in (2,3) and 型番 = 2 and 品番 = 2 then 1 else null end) 型番2品番2個数 ,sum(case when その他 in (2,3) and 型番 = 2 and 品番 = 1 then 売上 else 0 end) 型番2品番1売上 ,sum(case when その他 in (2,3) and 型番 = 2 and 品番 = 2 then 売上 else 0 end) 型番2品番2売上 ,sum(売上) 合計売上 from テーブル group by ユーザ番号,日付 order by ユーザ番号,日付; MySQLは詳しくないのですが、sum(型番=1) という書き方ができるのですね。

kanemoto_syoko
質問者

お礼

ご回答、誠にありがとうございました。 質問が判りにくくて、申し訳ありませんでした。 おかげで意図する結果を得る事ができました。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

ざっくりこんな感じ? select ユーザ番号,日付 ,sum(型番=1) AS 型番1個数 ,sum(型番=2) AS 型番2個数 ,sum((その他 IN (2,3))*(型番=2)*(品番=1)) AS その他が2か3で型番2・品番1個数 ,sum((その他 IN (2,3))*(型番=2)*(品番=1) * 売上) AS その他が2か3で型番1・品番1売上小計 ,sum((その他 IN (2,3))*(型番=2)*(品番=2)) AS その他が2か3で型番2・品番2個数 ,sum((その他 IN (2,3))*(型番=2)*(品番=2) * 売上) AS その他が2か3で型番2・品番1売上小計 ,sum(売上) AS 売上合計 from テーブル group by ユーザ番号,日付

kanemoto_syoko
質問者

お礼

ご回答、誠にありがとうございました。 質問が判りにくくて、申し訳ありませんでした。 おかげで意図する結果を得る事ができました。

関連するQ&A

  • SQLのUPDATE文(WHERE)で教えて下さい

    SQLのUPDATE文(WHERE)で教えて下さい SQL初心者なのですが、どなたか教えて頂けないでしょうか・・・。 Oracle10gにSqlPlusで接続してテーブルをUPDATEしようとしています。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   (空白) B1   XXX  T001   (空白) C1   ZZZ  T003   (空白) 【テーブル2】 品番、 規格、 取引先、 備考 A1   XXX  T001   あああ A1   YYY  T002   いいい B1   XXX  T001   ううう テーブル1の「日付」が(空白)のレコードを対象に、 テーブル1の「品番+規格+取引先」とテーブル2の「品番+規格+取引先」が同じな場合、 テーブル1の「日付」項目に今日の日付をUPDATEしたいと考えています。 結果を以下のようにしたいです。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   2010/03/19 B1   XXX  T001   2010/03/19 C1   ZZZ  T003   (空白) これが実現できるSQL文を教えて下さい。 宜しくお願い致します。

  • SQLで、指定日条件のSQL文

    MySQLを使っています。 商品テーブルの中で、 同じ商品のレコードが複数あります。 その多数のレコード中に、日付項目があります。 そこから、 1)商品IDで重複せずに、2)指定日に、3)一番近い過去の日、4)指定日を含めて、複数ある未来の全レコード、を抽出するには、 どのようなSQL文を書けばよいでしょうか? 商品でユニークになるように、 1.過去に複数ある日付の中から、指定日に、一番近いレコード。 2.未来に複数ある日付の中の、全ての未来の、レコード。 3.同一商品レコードは、複数抽出されない。

  • 効率的なSQL文が思いつきません

    いつもお世話になっております。 前回(多分1年ほど前) 質問させて頂いた際は丁寧に回答頂きまして感謝しております。 自分であれこれと思いめぐらせてみたのですが、これだと思うSQL文が思いつきませんでして、早速ですが質問をさせて頂きたいと思います。 テーブル構造 user_id ques_id result (プライマリーは別途)  001  1   1  002  1   0  003  1   1  004  1   1  002  2   1  003  2   0  001  3   1 … 学習のデータベースの初答の場合の結果を記録するものです。 user_idとques_idでユニークです。 例えば、1レコード目はユーザ001が 問題番号1を正解(result=1)したことを表します。 ※任意問題に対してすべてのユーザが  問題を解いているとは限りません。 ここで、取り出したい情報は ある任意の問題セット(例: (1,3,4,5))を全て解いているユーザ のuser_idとその問題セットの正答率です。 理想的な結果としては ある問題セットに対して user_id 正答率  001 3/4 のように出力されて欲しいです。 *私が考えたこと (SELECT * from テーブル WHERE ques_id = 1) as t1 LEFT JOIN (SELECT * from テーブル WHERE ques_id = 3) as t2 USING(user_id) って繋げてみて・・・どうするんだろう(???) これでもなんかいびつな感じがとってもします。 って感じです。 アドバイス頂ければ幸いです。

    • ベストアンサー
    • MySQL
  • SQLのUPDATE文に関して教えて下さい

    SQLのUPDATE文に関して教えて下さい まだまだ初心者で勉強中なのですが、ご教授をお願い致します。 2つのテーブルがあり同じ条件になったレコードのある項目を別のもう片方の項目にセットしたいのですが上手くいきません。 具体的には以下の通りです。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   (空白) B1   XXX  T001   (空白) C1   ZZZ  T003   (空白) 【テーブル2】 品番、 規格、 取引先、 受入日 A1   XXX  T001   2010/01/01 A1   YYY  T002   2010/03/01 B1   XXX  T001   (空白) テーブル1の「日付」が(空白)のレコードを対象に、 テーブル1の「品番+規格+取引先」とテーブル2の「品番+規格+取引先」が同じな場合、 テーブル1の「日付」項目にテーブル2の「日付」項目をUPDATEしたいと考えています。 結果を以下のようにしたいです。 【テーブル1】 品番、 規格、 取引先、 日付 A1   XXX  T001   2010/01/01 A1   YYY  T002   2010/03/01  ←ここが今回更新される B1   XXX  T001   (空白) C1   ZZZ  T003   (空白) 以前この場で教えて頂いたものを参考に以下のような感じで考えていたのですがエラーになります。 update テーブル1 set テーブル1.日付 = テーブル2.受入日 where テーブル1.日付 Is Null and (concat(concat(品番, 規格), 取引先)) in (select (concat(concat(品番, 規格), 取引先)) from テーブル2) ; ERROR at line 1: ORA-00904: "テーブル2"."受入日": invalid identifier set文のところの記述方法がわかりません。 宜しくお願い致します。

  • SQL文を教えてください。

    MYSQLを使っています。 【売上テーブル】 || 日付 || 金額 || ----------------- || 2011/01/01 || 100 || || 2011/01/01 || 200 || || 2011/01/02 || 600 ||           ・           ・           ・ || 2012/12/31 || 500 || || 2012/12/31 || 100 || SELECT SUM(金額) FROM 売上テーブル WHERE 日付 BETWEEN '2011-01-01' AND '2011-12-31' GROUP BY DATE_FORMAT(日付, '%Y/%m') で月初から月末のデータを表示させることはできますが、 2011/01/10~2011/02/09を一か月として 以降は 2011/02/10~2011/03/09 2011/03/10~2011/04/09        ・        ・        ・ 2011/12/10~2012/01/09 といった感じに1年間のデータを表示させる方法がわかりません。 どうぞ宜しくお願いします。

    • ベストアンサー
    • MySQL
  • SQL文で2つのSELCT文の結果を繋げる方法

    SQL文で2つのSELCT文の結果を繋げる方法はありますでしょうか。 Left Join でもと思ったのですが、片側にしかないのも、1レコードとして出力したいです。 テーブルの例と出力の理想は以下です。 また、上記の応用でこれを4テーブル(SELECT文)を繋げて、下記例で言うと、日付と商品コードがキーで、どのテーブルに存在しても、結果を1行で返せるでしょうか。 【テーブル1(SELECT文1)】 F_仕入 伝票日付 商品コード 仕入金額 2014/07/01 101     10,000 2014/07/02 102     15,000 2014/07/05 104 20,000 【テーブル2(SELECT文2)】 F_売上 伝票日付 商品コード 売上金額 2014/07/01 101     15,000 2014/07/02 102     25,000 2014/07/03 103 13,000 上記2つのSELECT結果 伝票日付  商品コード 仕入金額 売上金額 2014/07/01 101 10,000 15,000 2014/07/02 102 15000 25,000 2014/07/03 103 13,000 2014/07/05 104 20,000 よろしくお願いします。

  • どんなSQL文にすればいいか悩んでいます

    MySQLは「5.1」をCentOS5.8上で使っています。 - date,station 2013-11-01,urawa 2013-11-01,omiya 2013-11-01,omiya 2013-11-02,omiya 2013-11-02,akabane 2013-11-02,ikebukuro 2013-11-02,omiya - 日付ごとのdistinctなstationの個数について、 1ヶ月分の合計数を出すためのSQLを作りたいと思っています。 上の例で言うと、 2013-11-01はdistinctなstationは2個 2013-11-02はdistinctなstationは3個なので、 2013-11分の合計として、 「5」個という数を出したいと思っています。 - select count(distinct station) from table_name where date like '2013-11-%' - とすると日付の区別もなく、 固有のstationの個数として「4」個と出てきてしまい、 どうしていいか分からないでいます。 どんなSQLを作れば、 日付ごとの「distinctなstation数」の1ヶ月分の合計値を出すことが出来るでしょうか。 教えていただけますと幸いです。

    • ベストアンサー
    • MySQL
  • SQL 重複しないJoinの仕方を教えてください

    データが重複しないSQL文の書き方を教えてください。 下記のような2つのテーブルがあり、「管理番号」でOnして「使用数」をJoinさせ、かつ重複しないようにSQLを作成したいのですが、MySQLで可能でしょうか? ※0002に関しては、テーブル2の方がデータ数が多いため、Join後は2行になって「使用数」は重複せず、「数」の部分には0が入ればベストです 【テーブル1】 日付    品番  管理番号 数 2012/6/12 A987  0001 500 2012/6/14 A987  0001 300 2012/6/16 A987  0001 400 2012/6/18 A987  0001 800 2012/6/12 A987  0002 750 2012/6/12 A987  0003 540 2012/6/14 A987  0003 740 2012/6/16 A987  0003 840 2012/6/18 A987  0003 240 2012/6/20 A987  0003 640 【テーブル2】 日付    品番  管理番号 使用数 2012/7/10 A987  0001 160 2012/7/11 A987  0001 260 2012/7/10 A987  0002 220 2012/7/12 A987  0002 320 2012/7/20 A987  0003 530 2012/7/22 A987  0003 430 2012/7/24 A987  0003 830 【テーブルJoin】 日付    品番  管理番号 数 使用数 2012/6/12 A987  0001 500 160 2012/6/14 A987  0001 300 260 2012/6/16 A987  0001 400 0 2012/6/18 A987  0001 800 0 2012/6/12 A987  0002 750 220 2012/6/12 A987  0002 0 320 2012/6/12 A987  0003 540 530 2012/6/14 A987  0003 740 430 2012/6/16 A987  0003 840 830 2012/6/18 A987  0003 240 0 2012/6/20 A987  0003 640 0

  • 内部結合のSQL文

    次のような条件でのSQL文はどのように書けばよいのでしょうか? 売上テーブル(フィールドは「売上No.」)と売上明細テーブル(フィールドは「売上No.」「行番号」)を内部結合します。 結合の条件は売上明細テーブルの売上No.が売上テーブルの売上No.と等しいもの、かつ売上明細テーブルの行番号の一番小さいもの、です。 行番号はユニークですが、必ずしも1から順に振られているとは限りません。 どうぞよろしくお願いします。

  • 1つのSQLで2段階の抽出を行いたい

    恐らくそれほど複雑なSQLではないと思いますが、中々SQLが作成できず困っています。 回答いただければ嬉しいです。 以下のテーブルがあったと仮定します。 テーブル名:  売上げ明細 カラム:  ・商品ID … 売上げ明細なので一意ではありません  ・単価 … 同じ商品IDでも、レコードによって単価は異なります  ・数量 … 1~5の整数のみとします 実際のデータは以下の通りです。 商品ID,単価,数量 1001,50,2 1001,60,5 1002,90,3 1003,60,5 1003,80,4 1003,90,1 1004,60,3 上記データを以下の通り抽出するには、どのようなSQLを組めばいいでしょうか? 1.まず各商品IDの中から単価が最大のレコードだけを取り出す 商品ID,単価,数量 1001,60,5 1002,90,3 1003,90,1 1004,60,3 2.次に数量でgroup by して、件数をカウントする 数量,件数 1,1 3,2 5,1 1つのSQL文で2の結果が得られれば、途中の抽出条件は特に問いません。 ちなみにMySQL5を使っています。 よろしくお願いします。

    • ベストアンサー
    • MySQL