Can anyone explain the differences between following two requests:
SET @foundnow=0;
SELECT id, (@foundnow:=IF(`id`=3,1,0)) as ff
FROM `sometable`
HAVING @foundnow=0
result is
id ff
1 0
2 0
3 1
and
SET @foundnow=0;
SELECT id, (@foundnow:=IF(`id`=3,1,0)) as ff
FROM `sometable`
HAVING ff=0
result is
id ff
1 0
2 0
4 0
5 0
...
why first gives all rows up to id=3 (including), and second - all rows EXCEPT with id=3?
I guess related to this question is "unexpected" behavior of following request
SET @tot=0;
SELECT @tot:=@tot+1 as `ff`
FROM `anytable`
HAVING (`ff`>10)
which gives rows with ff=12,14,16,18...
@foundnow is NOT a per-row variable. It lives on. Creating a column ff makes it a per-row value. Also, from the documentation:
In a SELECT statement, each select expression is evaluated only when sent to the client. This means that in a HAVING, GROUP BY, or ORDER BY clause, referring to a variable that is `assigned a value in the select expression list does not work as expected:
Which means that your first example goes like:
And your second goes like:
So, the first example does not evaluate the expression at all if @foundrow!=0, because @foundrow is known and MySQL does not care what's in that select expression. The second one refers to a column in the resultset, and thus has to know that result, and performs the select.
Also, avoid HAVING clauses if you can if you can use WHERE's they are very much preferred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With