12.3.3 論理演算子

表 12.4 論理演算子

名前 説明
AND, && 論理 AND
NOT, ! 値を否定します
||, OR 論理 OR
XOR 論理 XOR

SQL では、すべての論理演算子は TRUEFALSE、または NULL (UNKNOWN) に評価されます。MySQL では、これらは 1 (TRUE)、0 (FALSE)、および NULL として実装されます。この大部分は、さまざまな SQL データベースサーバーに共通のものです。ただし、一部のサーバーは TRUE にゼロ以外の任意の値を返す場合があります。

MySQL では、ゼロ以外の任意の非 NULL 値が TRUE に評価されます。たとえば、次のステートメントはすべて TRUE に評価されます。

mysql> SELECT 10 IS TRUE;
-> 1
mysql> SELECT -10 IS TRUE;
-> 1
mysql> SELECT 'string' IS NOT NULL;
-> 1
  • NOT!

    NOT 演算。オペランドが 0 の場合は 1 に、オペランドがゼロ以外の場合は 0 にそれぞれ評価され、NOT NULL の場合は NULL が返されます。

    mysql> SELECT NOT 10;
            -> 0
    mysql> SELECT NOT 0;
            -> 1
    mysql> SELECT NOT NULL;
            -> NULL
    mysql> SELECT ! (1+1);
            -> 0
    mysql> SELECT ! 1+1;
            -> 1
    

    最後の例では、式が (!1)+1 と同様に評価されるため、1 が生成されています。

  • AND&&

    AND 演算。すべてのオペランドがゼロ以外で非 NULL の場合は 1 に、1 つ以上のオペランドが 0 の場合は 0 に評価され、それ以外の場合は NULL が返されます。

    mysql> SELECT 1 && 1;
            -> 1
    mysql> SELECT 1 && 0;
            -> 0
    mysql> SELECT 1 && NULL;
            -> NULL
    mysql> SELECT 0 && NULL;
            -> 0
    mysql> SELECT NULL && 0;
            -> 0
    
  • OR||

    論理 OR。両方のオペランドが非 NULL であれば、オペランドのいずれかがゼロ以外である場合の結果は 1、それ以外の場合は 0 になります。NULL オペランドが 1 つあれば、ほかのオペランドがゼロ以外である場合の結果は 1、それ以外の場合は NULL になります。両方のオペランドが NULL であれば、結果は NULL になります。

    mysql> SELECT 1 || 1;
            -> 1
    mysql> SELECT 1 || 0;
            -> 1
    mysql> SELECT 0 || 0;
            -> 0
    mysql> SELECT 0 || NULL;
            -> NULL
    mysql> SELECT 1 || NULL;
            -> 1
    
  • XOR

    論理 XOR。オペランドのいずれかが NULL である場合は、NULL を返します。非 NULL のオペランドでは、奇数のオペランドがゼロ以外の場合は 1 に評価され、それ以外の場合は 0 が返されます。

    mysql> SELECT 1 XOR 1;
            -> 0
    mysql> SELECT 1 XOR 0;
            -> 1
    mysql> SELECT 1 XOR NULL;
            -> NULL
    mysql> SELECT 1 XOR 1 XOR 1;
            -> 1
    

    a XOR b は、数学的に (a AND (NOT b)) OR ((NOT a) and b) に等しくなります。


User Comments
  Posted by Chris Lacy-Hulbert on June 2, 2003
XOR is useful for throwing a boolean switch with just a single query. For example:

mysql> update mytable set mytable.switch=1 XOR mytable.switch where [condition];

will toggle a boolean field 'switch' from 1 to 0 or 0 to 1.

Hope that's useful,
christo
  Posted by Matt on September 19, 2003
An alternative to your use of XOR is ABS(x-1) if you are using 0 and 1 switches.
  Posted by Joël Larose on October 20, 2003
Or you could just use the NOT operator, as in

update mytable set mytable.switch=NOT mytable.switch where [condition];
  Posted by W L on October 19, 2005
Note that the ! operator was on the same level of precedence as the NOT operator, until 5.02, when it is at a higher level.

See the page on "12.1.1. Operator Precedence" for the precedence for all the operators.
  Posted by Toby Thain on April 6, 2006
Or just '1-X'
  Posted by Marnen Laibow-Koser on May 24, 2006
The documentation doesn't say anything about this, but it appears (based on some tests I just ran) that MySQL short-circuits evaluation of logical operators just like most other languages do.
  Posted by Dredwerkz Dredwerkz on November 24, 2010
/*
* This is what I did to find out whether both AND, OR, &&, ||, &, | work as short circuit logical operators or not.
*
* Testing OR operand:
*/
SET @my_var := NULL;
SELECT IF(0 < 1 OR @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 > 1 OR @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* The output:
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | A | NULL | A | 1 |
* +-------+---------+-------+---------+
* 1 row in set (0.01 sec)
*
* Testing AND operand:
*/
SET @my_var := NULL;
SELECT IF(0 > 1 AND @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 < 1 AND @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* The output:
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | B | NULL | B | 0 |
* +-------+---------+-------+---------+
* 1 row in set (0.00 sec)
*
* Testing || operand:
*/
SET @my_var := NULL;
SELECT IF(0 < 1 || @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 > 1 || @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | A | NULL | A | 1 |
* +-------+---------+-------+---------+
* 1 row in set (0.00 sec)
*
* Testing && operand:
*/
SET @my_var := NULL;
SELECT IF(0 > 1 AND @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 < 1 AND @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* The output:
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | B | NULL | B | 0 |
* +-------+---------+-------+---------+
* 1 row in set (0.00 sec)
*
* Testing the | operand:
*/
SET @my_var := NULL;
SELECT IF(0 < 1 | @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 > 1 | @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* The output:
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | A | 1 | B | 0 |
* +-------+---------+-------+---------+
* 1 row in set (0.00 sec)
*
* Testing the & operand:
*/
SET @my_var := NULL;
SELECT IF(0 > 1 & @my_var := (1 < 0), 'A', 'B') AS `rslt.`,
@my_var,
IF(0 < 1 | @my_var := (1 > 0), 'A', 'B') AS `rslt.`,
@my_var;
/*
* The output:
* Query OK, 0 rows affected (0.00 sec)
*
* +-------+---------+-------+---------+
* | rslt. | @my_var | rslt. | @my_var |
* +-------+---------+-------+---------+
* | B | 0 | A | 1 |
* +-------+---------+-------+---------+
* 1 row in set (0.01 sec)
*
*
* Summary:
* +---------+----------------+
* | Operand | Short-circuit? |
* +---------+----------------+
* | OR | Yes |
* +---------+----------------+
* | AND | Yes |
* +---------+----------------+
* | || | Yes |
* +---------+----------------+
* | && | Yes |
* +---------+----------------+
* | | | No |
* +---------+----------------+
* | & | No |
* +---------+----------------+
*/

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