简体   繁体   中英

Where clause without operator

While trying to answer this question , I found a syntax which I would have considered wrong

select * from table where area and block

I tried an sqlFiddle, and found it was valid.

But I've been unable to find how it works (all the doc I found was including operators)...

Made some try on an sql fiddle here

It seems to "eliminate" null and 0 results for an nullable int field, or 0 result for a non nullable int field.

It also looks like it keeps varchar values... which contains int values (but not '0') !

Even if I don't think it's a good idea (at all) to use such syntax, I would appreciate if someone had any explanation on how this is managed...

From the MySQL documentation for Logical Operators :

MySQL evaluates any nonzero, non-NULL value to TRUE. For example, the following statements all assess to TRUE:

mysql> SELECT 10 IS TRUE;<br/>
-> 1
mysql> SELECT -10 IS TRUE;<br/>
-> 1
mysql> SELECT 'string' IS NOT NULL;<br/>
-> 1

It seems that it evaluates any non-zero int field as TRUE . Also, any varchar field which contains a number gets treated as numeric field. I checked in your fiddle that a varchar field of '0' does not evaluate to TRUE . And any varchar field which cannot be converted to a number does not evaluate to TRUE unless it is part of an IS NOT NULL expression. Hence:

mysql> SELECT 'string' IS TRUE;<br/>
-> 0

From testing your fiddle, I found the following 2 queries to behave identically:

select * from test where ttt;
select * from test where ttt IS TRUE;

I don't have any definitive proof or source code, but it appears that MySQL actually is using an operator on the first query above even if it be omitted.

To add some clarification to the answer from Tim Biegeleisen...

In a WHERE clause, MySQL evaluates the expression as a boolean value. If the result of that expression is TRUE, the row is returned. Otherwise, the row is excluded.

The expression in the WHERE clause is not required to have a comparison operator. But it is convenient that the result from a comparison operator/operation (for example, foo = 'x' ) is a boolean value.

In MySQL, a boolean TRUE value is represented as integer value 1 , FALSE is represented as integer value 0 , and NULL (of course) is NULL . And we can observe this behavior, eg

 SELECT TRUE + TRUE AS c1, FALSE AS c2

returns:

   c1    c2  
 ----  ----
    2     0

In MySQL, there are a lot of expressions that can be evaluated in boolean context. (I can't think of an expression offhand that cannot be, though MySQL does seem to get squirrelly with expressions that return DECIMAL values.)

Tim's answer suggests that MySQL is adding an IS TRUE comparison, and that these two statements are evaluated equivalently:

  SELECT * FROM test WHERE ttt;
  SELECT * FROM test WHERE ttt IS TRUE;

That's not too far off, because in a lot of cases, those queries do return the same result. But that's not really the best explanation, because those two statements are actually evaluated differently; these return different results in some corner cases. As a demonstration, consider:

  CREATE TABLE test (ttt DECIMAL(18,9) PRIMARY KEY);
  INSERT INTO test (ttt) VALUES (0.48);

One the statements returns a row, the other doesn't. SQL Fiddle here: http://sqlfiddle.com/#!9/63960/1


It's really the WHERE clause that's requiring the expression to be evaluated as a boolean. That excludes rows where the expression does not evaluate to TRUE.

The foo IS TRUE is a test of the expression foo against a boolean value. Reference: https://dev.mysql.com/doc/refman/5.6/en/comparison-operators.html#operator_is

We'd expect these to be the same, but as demonstrated earlier, the IS TRUE test can give a different result than the evaluation of the expression in a WHERE clause.


In the WHERE clause, the expression is being evaluated as a boolean.

Evaluation integer values in boolean context is relatively easy... a NULL is (of course) NULL, an integer value of 0 is FALSE, and any other non-zero integer value is TRUE .

Evaluation of decimal/numeric values is a little more squirrelly, with values of foo, where -0.5 > foo > 0.5 , in a boolean context, those values don't evaluate to TRUE. We workaround that squirrely-ness by building an expression to make the conversion explicit, instead defaulting to MySQL's implicit rounding behavior:

  SELECT * FROM test WHERE CEIL(ABS(ttt));

Even character strings can be evaluated in boolean context. MySQL implicitly casts the character string to a numeric. And then follows the same rules it does for numeric values.

A SQL expression that better matches the evaluation of foo in the WHERE clause is:

  ABS(SIGN(ROUND(t.foo+0,0))) AS `ASR foo+0`

(I'm not saying that this is actually the operation that MySQL is performing; I'm just saying this expression gets us a return that more closely matches the operation that MySQL performs.)

For various character values of foo:

  foo      foo+0  foo IS TRUE  ASR foo+0  WHERE foo
  ------  ------  -----------  ---------  ---------
  7x           7            1          1        yes
  -2.4      -2.4            1          1        yes
  0.0123  0.0123            1          0        no
  0            0            0          0        no
  (NULL)  (NULL)            0      (NULL)       no

It basically display all database results without any filtering. If some operator is used, the query will run on that operator condition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM