

MySQLでのcaseとwhereについて質問です。  
以下のようなテーブルがあります。

[code]

    project_id|item_id|value
    ----------+-------+-----
    1         |67     |5
    1         |68     |5
    2         |67     |6
    2         |68     |6
    
[/code]

item_idが67が5以上かつitem_id68が５以上のproject_idを求める SQLで困ってます。

以下のようにcase文で縦持ちを横にします。

[code]

    SELECT 
        project_id,
            MIN(CASE item_id
                WHEN 67 THEN value
            END) AS 'c67',
            MIN(CASE item_id
                WHEN 68 THEN value
            END) AS 'c68'
    FROM
        results
    
[/code]

上記で以下が取れます。

[code]

    project_id|c67|c68
    ----------+---+-----
    1         |5  |5
    
[/code]

**編集者註記：project_idが2のものは取得できないので除外**

上記のSQLをサブクエリにすれば取れると思い以下のSQLを書きました。

[code]

    SELECT 
    *
    FROM
        (SELECT 
            project_id,
                MIN(CASE item_id
                    WHEN 67 THEN value
                END) AS 'c67',
                MIN(CASE item_id
                    WHEN 68 THEN value
                END) AS 'c68'
        FROM
            results
        GROUP BY project_id) AS temp
    WHERE
        'c67' >= 5 AND 'c68' >= 5
    
[/code]

しかし、０件になってしまいます。

case文を使ったカラムには条件を指定できないのでしょうか？

よろしくお願いします。


CC BY-SA 3.0
2015-11-21T15:06:16.637
19137
2016-06-23T15:32:41.750
2015-11-21T16:02:29.363
5778
10092
question
sql
MySQLでcase文のカラムにwhereで条件指定できない


最終行にてシングルクォートでカラム名を指定されている箇所に問題がありました。

MySQLではカラム名をくくる記号は `(@+SHIFT) です。

ですので、WHERE句は、次のようにすると期待される動作になると思います。

[code]

    WHERE `c67` >= 5 and `c68` >=5
    
[/code]

以下、余談です。

2つのSQLを比較してみましたが、下のSQLにはGROUP BYにてproject_idで絞り込んでいますが、上のSQLでは特に絞り込んでいませんでした。  
そのためSQLの実行結果については、 **編集者註記** の行にて訂正しました。


CC BY-SA 3.0
2015-11-21T16:11:09.550
19141
2015-11-21T16:11:09.550
5778
19137
answer


サブクエリではなく、`HAVING` を使ってみてはいかがでしょうか。

[code]

    SELECT * FROM results;
    =>
    +------------+---------+-------+
    | project_id | item_id | value |
    +------------+---------+-------+
    |          1 |      67 |     5 |
    |          1 |      68 |     5 |
    |          2 |      67 |     6 |
    |          2 |      68 |     6 |
    |          3 |      67 |     4 |
    |          3 |      68 |     8 |
    +------------+---------+-------+
    
    SELECT 
        project_id,
            MIN(CASE item_id
                WHEN 67 THEN value
            END) AS 'c67',
            MIN(CASE item_id
                WHEN 68 THEN value
            END) AS 'c68'
    FROM
        results
    GROUP BY project_id
    HAVING c67 >= 5 AND c68 >= 5
    =>
    +------------+------+------+
    | project_id | c67  | c68  |
    +------------+------+------+
    |          1 |    5 |    5 |
    |          2 |    6 |    6 |
    +------------+------+------+
    
[/code]


CC BY-SA 3.0
2015-11-21T17:15:38.020
19142
2015-11-21T17:36:30.817
2015-11-21T17:36:30.817
19137
answer


別解

[code]

    SELECT a.project_id, a.value c67, b.value c68 
    FROM (
        SELECT project_id, value FROM results WHERE item_id = 67 AND value >= 5
    ) AS a INNER JOIN (
        SELECT project_id, value FROM results WHERE item_id = 68 AND value >= 5
    ) AS b ON a.project_id = b.project_id;
    
[/code]

project_id と item_id が複合ユニークであれば、上記SQL文でも期待する結果を取得できます。  
<http://sqlfiddle.com/#!9/1ca66/1>


CC BY-SA 3.0
2016-06-23T15:32:41.750
27013
2016-06-23T15:32:41.750
16934
19137
answer