Limit Results from mysql using if statement - mysql

I've got if statement code that works for the where clause of mysql query, but not for the limit statement. Could someone please help me to get this to work or a similar alternative? It gives me an expected result Boolean error.
I'm trying to use the if statement to find out if the $limit variable has any value except OFF. If it does, then limit the results of the mysql query by whatever number, 20 in this case. I'm not sure if that helps.
I honestly don't know if this the correct way of doing this.
$limit='20'; or whatever number
IF('$limit'<>'OFF',LIMIT $limit,'$limit'=0)

you could avoid if using a ternary operator
$limit='20'; or whatever number
$limit_result = ($limit<>'OFF' ? $limit : 0);

Related

MySQL 5.7 RAND() and IF() without LIMIT leads to unexpected results

I have the following query
SELECT t.res, IF(t.res=0, "zero", "more than zero")
FROM (
SELECT table.*, IF (RAND()<=0.2,1, IF (RAND()<=0.4,2, IF (RAND()<=0.6,3,0))) AS res
FROM table LIMIT 20) t
which returns something like this:
That's exactly what you would expect. However, as soon as I remove the LIMIT 20 I receive highly unexpected results (there are more rows returned than 20, I cut it off to make it easier to read):
SELECT t.res, IF(t.res=0, "zero", "more than zero")
FROM (
SELECT table.*, IF (RAND()<=0.2,1, IF (RAND()<=0.4,2, IF (RAND()<=0.6,3,0))) AS res
FROM table) t
Side notes:
I'm using MySQL 5.7.18-15-log and this is a highly abstracted example (real query is much more difficult).
I'm trying to understand what is happening. I do not need answers that offer work arounds without any explanations why the original version is not working. Thank you.
Update:
Instead of using LIMIT, GROUP BY id also works in the first case.
Update 2:
As requested by zerkms, I added t.res = 0 and t.res + 1 to the second example
The problem is caused by a change introduced in MySQL 5.7 on how derived tables in (sub)queries are treated.
Basically, in order to optimize performance, some subqueries are executed at different times and / or multiple times leading to unexpected results when your subquery returns non-deterministic results (like in my case with RAND()).
There are two easy (and likewise ugly) workarounds to get MySQL to "materialize" (aka return deterministic results) these subqueries: Use LIMIT <high number> or GROUP BY id both of which force MySQL to materialize the subquery and return the expected results.
The last option is turn off derived_merge in the optimizer_switch variable: derived_merge=off (make sure to leave all the other parameters as they are).
Further readings:
https://mysqlserverteam.com/derived-tables-in-mysql-5-7/
Subquery's rand() column re-evaluated for every repeated selection in MySQL 5.7/8.0 vs MySQL 5.6

property of non-object to change value to 0

I have a curious question that's going on my mind while looking at my datatables.
I noticed that some columns of my table has no values, like just the column only.
Is it possible when you want to call that column it will return a value of 0?
I tried to call it with a simple SELECT query in sql but its giving me a notice.
Notice: Trying to get property of non-object MySQL result on line (number line)
Can this be used with an if-else statement from the query or a case statement from the query? Hoping for your opinions on this. Thank you :)
Try to use some function like NVL() in Oracle, or IFNULL() in MySQL. This functions set a value when you got a NULL value.

Symfony 2 - Doctrine ORM Update query not working

I am trying to update a mysql table with following query using Doctrine. But the table is not get updated. Also below code didnt throw any error. I am totally confused. If i run the query, taken from getDQL() method, in mysql directly it showing 0 rows updated becuase of inproper qoutes. it is working after placed proper qoutes for values in the query. Need help to solve this puzzle.
Since i am new to doctrine, i will use the examples give in querybuilder class file.
$support = $this->createQueryBuilder('p')
->update('gcns', 'g')
->set("g.isActive", "0")
->andWhere("g.issn='".$issn."'");
Do you ever execute the query or are you just building it? You should have something along these lines to execute it:
$support->getQuery()->getSingleScalarResult();
If i run the query, taken from getDQL() method, in mysql directly it showing 0 rows updated becuase of inproper qoutes.
getDQL() returns DQL not SQL, so it will have improper quotesif you try to run it directly inside MySQL, but that's expected.
You shouldn't concatenate $issn into your query. You should use parameters instead:
$qb = $this->createQueryBuilder()
$support = $qb->update('gcns', 'g')
->set('g.isActive', '0')
->andWhere( $qb->expr()->eq('g.issn', ':issn') )
->setParameter( 'issn', $issn )
->getQuery()->getSingleScalarResult()
;

Eloquent count distinct returns wrong totals

i'm having an issue with how eloquent is formulation a query that i have no access to. When doing something like
$model->where('something')
->distinct()
->paginate();
eloquent runs a query to get the total count, and the query looks something like
select count(*) as aggregate from .....
The problem is that if you use distinct in the query, you want something like
select count(distinct id) as aggregate from .....
to get the correct total. Eloquent is not doing that though, thus returning wrong totals. The only way to get the distinct in count is to pass an argument through the query builder like so ->count('id') in which case it will add it. Problem is that this query is auto-generated and i have no control over it.
Is there a way to trick it into adding the distinct on the count query?
P.S Digging deep into the builders code we find an IF statement asking for a field on the count() method in order to add the distinct property to the count. Illuminate\Database\Query\Grammars\BaseGrammar#compileAggregate
if ($query->distinct && $column !== '*')
{
$column = 'distinct '.$column;
}
return 'select '.$aggregate['function'].'('.$column.') as aggregate';
P.S.1 I know that in SQL you could do a group by, but since i'm eager loading stuff it is not a good idea cause it will add a IN (number of id's found) to each of the other queries which slows things down significantly.
I faced the exact same problem and found two solutions:
The bad one:
$results = $model->groupBy('foo.id')->paginate();
It works but it will costs too much memory (and time) if you have a high number of rows (it was my case).
The better one:
$ids = $model->distinct()->pluck('foo.id');
$results = $query = $model->whereIn('foo.id', $ids)->paginate();
I tried this with 100k results, and had no problem at all.
This seems to be a wider problem, discussed here:
https://github.com/laravel/framework/issues/3191
https://github.com/laravel/framework/pull/4088
Untill the fixes are shipped with one of the next Laravel releases, you can always try using the raw expressions, like below (I didnt test it, but should work)
$stuff = $model->select(DB::raw('distinct id as did'))
->where('whatever','=','whateverelse')
->paginate();
Reference: http://laravel.com/docs/queries#raw-expressions
$model->where('something')->distinct()->count('id')->paginate();

func.max get unexpected result?

I've got a table (story_id, votes)
with data
[(1,3), (2,4)]
when I try to do a query...
session.query(table.c.story_id, func.max(table.c.votes)).first()
i'll get:
(1,4)
the result I expect is:
(2,4)
where is the misunderstanding?
You are not grouping by anything so the database can simply return any row with a query like this. If you would add a group_by=table.c.story_id than this would return the proper result.
Most databases would, because of this, block these queries by default since the returned result would be arbitrary. In PostgreSQL for example you would get an error that story_id is not part of an aggregate query and not in the group by clause so it wouldn't know what row to return.
Either way, try this: session.query(table.c.story_id, func.max(table.c.votes)).group_by(table.c.story_id).first()