Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.1Mb
HTML Download (Zip) - 7.2Mb

12.4 制御フロー関数

表 12.6 フロー制御演算子

名前 説明
IF() If/else 構文
IFNULL() Null if/else 構文
NULLIF() expr1 = expr2 の場合に NULL を返します

  • CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN result ...] [ELSE result] END

    CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END

    1 番目のバージョンでは、value=compare_value の場合に result が返されます。2 番目のバージョンでは、true である最初の条件の結果が返されます。一致する結果値がなかった場合は、ELSE のあとの結果が返され、ELSE 部分がない場合は、NULL が返されます。

    mysql> SELECT CASE 1 WHEN 1 THEN 'one'
        ->     WHEN 2 THEN 'two' ELSE 'more' END;
            -> 'one'
    mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
            -> 'true'
        ->     WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
            -> NULL

    CASE 式の戻り型は、すべての戻り値の互換性のある集約型ですが、使用されるコンテキストにも依存します。文字列のコンテキストで使用される場合は、結果は文字列として返されます。数値のコンテキストで使用される場合は、結果が 10 進数値、実数値、または整数値として返されます。


    ここで示す CASE の構文は、ストアドプログラム内部で使用するために、セクション13.6.5.1「CASE 構文」で説明した SQL CASE ステートメントの構文とはわずかに異なります。CASE ステートメントは ELSE NULL 句を持つことができず、END でなく、END CASE で終了します。

  • IF(expr1,expr2,expr3)

    expr1TRUE (expr1 <> 0 および expr1 <> NULL) の場合、IF()expr2 を返します。それ以外の場合は expr3 を返します。IF() は、使用されているコンテキストに応じて、数値または文字列値を返します。

    mysql> SELECT IF(1>2,2,3);
            -> 3
    mysql> SELECT IF(1<2,'yes','no');
            -> 'yes'
    mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
            -> 'no'

    expr2expr3 の一方のみが明示的に NULL である場合は、IF() 関数の結果型は非 NULL 式の型になります。

    IF() のデフォルトの戻り値 (一時テーブルに格納されるときに重要となる場合があります) は、次のように計算されます。

    expr2 または expr3 は文字列を返す 文字列
    expr2 または expr3 は浮動小数点値を返す 浮動小数点
    expr2 または expr3 は整数を返す 整数

    expr2expr3 の両方が文字列で、どちらかの文字列で大文字と小文字が区別される場合は、結果でも大文字と小文字が区別されます。


    IF ステートメントもありますが、ここで説明されている IF() 関数とは異なります。セクション13.6.5.2「IF 構文」を参照してください。

  • IFNULL(expr1,expr2)

    expr1NULL でない場合、IFNULL()expr1 を返し、それ以外の場合は expr2 を返します。IFNULL() は、使用されているコンテキストに応じて、数値または文字列値を返します。

    mysql> SELECT IFNULL(1,0);
            -> 1
    mysql> SELECT IFNULL(NULL,10);
            -> 10
    mysql> SELECT IFNULL(1/0,10);
            -> 10
    mysql> SELECT IFNULL(1/0,'yes');
            -> 'yes'

    IFNULL(expr1,expr2) のデフォルトの結果値は、STRINGREAL、または INTEGER の順に、2 つの式のよりも一般的です。式や MySQL が一時テーブルの IFNULL() で返された値を内部に格納する必要のある場所に基づいて、テーブルの大文字と小文字を考慮してください。

    mysql> CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
    mysql> DESCRIBE tmp;
    | Field | Type         | Null | Key | Default | Extra |
    | test  | varbinary(4) | NO   |     |         |       |

    この例では、test カラムの型は VARBINARY(4) です。

  • NULLIF(expr1,expr2)

    expr1 = expr2 が true の場合は NULL を返し、それ以外の場合は expr1 を返します。これは、CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END と同じです。

    mysql> SELECT NULLIF(1,1);
            -> NULL
    mysql> SELECT NULLIF(1,2);
            -> 1

    引数が等しくない場合は、MySQL で expr1 が 2 回評価されます。

User Comments
User comments in this section are, as the name implies, provided by MySQL users. The MySQL documentation team is not responsible for, nor do they endorse, any of the information provided here.
  Posted by sebastian nielsen on September 12, 2010
Milan: How is it useful to run:


instead of:

SELECT * FROM table WHERE field = 1

the IFNULL(NULL, field = 1) would always return field = 1.

But the IFNULL() is good in cases you want to do a insert and clamp a value to a value that is already in record, else set it at maximum.

For example this:

INSERT INTO users (type,class,username,userid,userip,usermobile,useremail,daysleft,pin1,pin2,pin3,active,schoolname,schoolsite) SELECT 'A','A','sebastian',1000,'','none','',(SELECT IFNULL(MIN(daysleft),30) from users WHERE userip='' AND type='A'),'12345','12345','00000','N','none','none' FROM dual WHERE ((SELECT COUNT(*) FROM users WHERE userip='' AND type='A' AND daysleft = 0) = 0);

The interesting part is this:
(SELECT IFNULL(MIN(daysleft),30) from users WHERE userip='' AND type='A')

If theres a record in the table for the user's IP, upon registrering for a account, it will take the smallest daysleft found, else it will give the user 30 days in daysleft.

This is good for example if you want to give 30 days trial period, and still allow members in a household to register for their own accounts, but not allowing longer trial priod by registrering multiple own accounts.

In this case, if a household has a user with lets say 10 trial days left, and a another user in the household registers himself for a account, that user will too get 10 trial days left.
If theres no accounts on a specific household, the user will get a full 30 days trial period.
  Posted by Joseph Edmonds on January 19, 2012
Note using the case syntax you can update many rows with one query. This can have a really dramatic postitive impact on performance if you have a large number of updates to do.

For a nice PHP function to handle this see here:

  Posted by Mike Jorgenstam on February 28, 2014
This does not work to validate that all actually fall within as some can have > 1 five while still being within 20 sum and then discards second statement after OR

Thus, MySQL reads the passed if clause in the statement from LEFT TO RIGHT and not from RIGHT TO LEFT as some say...

-- This fails
IF ((@r7q0+@r7q1+@r7q2+@r7q3+@r7q4+@r7q5) < 20) OR
OR (@r7q5 > 1) THEN
SET @res = 0;

-- This works
IF ((@r7q6+@r7q7+@r7q8+@r7q9+@r7q10) > 0) OR (@r7q5 > 1) THEN
SET @res = 0;

-- This would work in some cases then
IF (@r7q5 > 1) OR
((@r7q0+@r7q1+@r7q2+@r7q3+@r7q4+@r7q5) < 20) THEN
SET @res = 0;

Sign Up Login You must be logged in to post a comment.