19031


**カラム**  
name,level(int),hoge(int)

* * *

**SQL1**

[code]

    SELECT name,
           SUM( CASE WHEN level = '1' THEN
                          hoge ELSE 0 END),
           SUM( CASE WHEN level = '2' THEN
                          hoge ELSE 0 END)
    FROM `テーブル名`
    GROUP BY name;
    
[/code]

* * *

**SQL2**  
・意味が分からないので、SUMを外してみました  
・3番目のカラムhogeが全て0になりました

[code]

    SELECT name,
           ( CASE WHEN level = '1' THEN
                          hoge ELSE 0 END),
           ( CASE WHEN level = '2' THEN
                          hoge ELSE 0 END)
    FROM `テーブル名`
    GROUP BY name;
    
[/code]

* * *

**SQL3**  
・SUMを一つだけ追記  
・最初と同じ結果になりました

[code]

    SELECT name,
           ( CASE WHEN level = '1' THEN
                          hoge ELSE 0 END),
           SUM( CASE WHEN level = '2' THEN
                          hoge ELSE 0 END)
    FROM `テーブル名`
    GROUP BY name;
    
[/code]

* * *

**質問**  
・SQL2で、どうして3番目のカラムhogeが全て0になるのでしょうか？ 実行されていない？  
・SQL1とSQL3は同じ意味？  
・そもそもどういう順番で実行されるのでしょうか？  
・最初に実行されるのは、`SELECT name FROM テーブル名 GROUP BY name;`？  
・次に実行されるのは、`SELECT SUM( CASE WHEN level = '1' THEN hoge ELSE 0 END) FROM テーブル名
GROUP BY name;`？


CC BY-SA 3.0
2015-11-19T05:38:49.090
19021
2015-11-19T07:43:15.927
7886
question
mysql
MySQLで、GROUP BY 後、SUMする挙動が理解できないのですが、


SQL1は標準的なSQLですね。

SQL2はGROUP BYからカラム2とカラム３を省略した物で、MySQL以外ではエラーになります。この時、カラム２、カラム３の値は予測不可能になります。

SQL3も同じくGROUP
BYからカラム2省略した物で、MySQL以外ではエラーになります。この時、カラム２の値は予測不可能になります。カラム3にはSQL1と同じ結果が格納されます。

おそらくCASE式が分からなかったのだと思いますが、CASE式はWHERE文で抽出した各行に対して論理演算を行う物です。したがってWHERE文による抽出後に行われます。SQL1ではCASE式の結果に対して集計していますが、逆に集計した結果に対してCASE式を適用することも出来ます。


CC BY-SA 3.0
2015-11-19T06:26:52.277
19025
2015-11-19T06:26:52.277
12774
19021
answer


name別にhogeの値を集計したいときは

[code]

    SELECT name, SUM(hoge) FROM `テーブル名` GROUP BY name;
    
[/code]

となります。

ここでlevelが'1'のレコードのみ集計したい場合、

[code]

    SELECT name,
           SUM(CASE WHEN level = '1' THEN hoge ELSE 0 END)
    FROM `テーブル名`
    GROUP BY name;
    
[/code]

と書くことが出来ます。  
（levelが'1'以外のレコードは0として集計されています）

さらにlevelが'1'と'2'の結果を同時に取得したい場合がSQL1の構文に該当します。

また、別の集計方法として

[code]

    SELECT name, level, SUM(hoge)
    FROM `テーブル名`
    GROUP BY name, level
    
[/code]

としてもname別＋level別の結果が得られます。  
（WHERE句を使えばlevelの条件指定も可能です）

SQL2, SQL3に関しては構文的におかしいのであまり深く考えなくてもよいかと。


CC BY-SA 3.0
2015-11-19T07:10:32.437
19031
2015-11-19T07:43:15.927
2015-11-19T07:43:15.927
13314
13314
19021
answer