Laravel 3 Eloquent: Looking for a "where_nested()" example - laravel

I have a custom validation rule that is checking the DB for NULL.
I need to look for null or empty.
HAVE:
$query = $this->db()->table($table);
...
foreach( $null_columns as $col )
$query->where_null($col);
Which results in something like: SELECT * FROM t WHERE col1=foo AND col2 IS NULL
WANT:
SELECT * FROM t WHERE col1=blah AND (col2 = '' OR col2 IS NULL)
QUESTION:
Is where-nested() the right tool for the job?
If so, I'd really like to see an example.
If not, what's a good way to approach this?

Well, I ended up getting it to work this way:
$query = $this->db()->table($table);
...
foreach( $null_columns as $col )
{
$query->where(function($q) use($col){
$q->where($col,'=','');
$q->or_where_null($col);
});
}
... but would still like to see an example of using where_nested() to do this, if possible. I always appreciate learning something new :)

Related

Codeigniter Query binding multiple fields with the same value

I'm in a situation where I'm doing a MySQL query with Codeigniter and where I have a lot of fields value request which are ALL the same.
Example:
$this->db->query('SELECT * FROM abc WHERE user_id = ? AND msg_from = ? AND msg_to != ?', [$id, $id, $id]);
This has just 3 question marks but the query I'm working on is HUGE and has 19 question marks WHICH ARE ALL THE SAME variable.
So I was trying to figure out how to tell Codeigniter all question marks are pointing to the same variable without having to fill an array with 19 times the same variable.
I thought of a for-loop but I wanted to know if a shortcut exist.
you should be able to do this with Codeigniters Query Builder pretty easily
Something like that should work:
$this->db
->select('*')
->from('abc');
$arrFields = array('users_id', 'msg_from', 'msg_to');
foreach($arrFields AS $val)
{
$this->db->where($val, $id);
}
$query = $this->db->get();

conditional where in codeigniter : apply where if previous where satisfied

I am trying to retrieve data from table using codeigniter.
doing something like that:
....
$this->db->where('course_request.enrollment_policy !=', '2');
//I want to write next statements something like:
$this->db->if_where('course_request.enrollment_policy ', '3')
then
$this->db->where('course_request.status', '3');
else
other codeigniter where_in
Hope you got my problem.
Looking for solution, Thanks in advance.
Solved.
who says it is not possible in CI?
$this->db->where('(CASE WHEN `course_request`.`enrollment_policy` = 3 THEN `course_request`.`status` = "3" ELSE course_request.status="0" OR course_request.status = "3" END )' , NULL,FALSE);
Just paste this in your where :
AND (
CASE
WHEN `course_request`.`enrollment_policy` = 3
THEN `course_request`.`status` = '3'
ELSE 1=1
END
)
and give second param NULL , third param FALSE

Joomla database query SELECT AS

So I'm just hypothetically thrilled to be querying my hypothetical database:
$query->select($db->quoteName(array('user_id', 'name')));
I would, however, like the query to look like:
SELECT `user_id` AS `uid`, `name` AS `User-Name`
How the heck do I get the AS in there?
I know this question is 6 months old, so you've probably found an answer or worked around it, but for anyone else who has a similar problem:
$query->select($db->quoteName(array('user_id','name'),array('uid','User-Name')));
If you only want to use an alias for some fields, just pass null in the array for the fields you don't want to alias, so for example:
$query->select($db->quoteName(array('user_id','name'),array(null,'User-Name')));
would give
"SELECT `user_id`, `name` AS `User-Name`"
My preferred way is this:
I create an array with the fields I want to select:
$fields = array(
'a.id' => 'id',
'a.field1' => 'field1',
'a.field2' => 'field2',
'a.field3' => 'field3',
'b.field1' => 'bfield1',
'b.field2' => null,
'b.field3' => 'bfield3',
);
In the above array, the keys are used for the db Column names of the query, the values for the aliases, as you can see later in the $query->select().
*When you do not need an alias - just set null.
This helps better to control and check what fields I want and how to name them - and is better for maintenance or changes and is portable enough, as I only have to change my $fields array according to my needs.
Then the Joomla select command can be like:
$query->select( $db->quoteName(
array_keys($fields),
array_values($fields)
));
This will produce the following SQL SELECT query:
SELECT `a`.`id` AS `id`,`a`.`field1` AS `field1`,`a`.`field2` AS
`field2`,`a`.`field3` AS `field3`,`b`.`field1` AS
`bfield1`, `field2`, `b`.`field3` AS `bfield3`
Try the following:
$query->select($db->quoteName('user_id') .' AS '. $db->quoteName('name') .' AS '. $db->quoteName('User-Name'));
Be sure to use the full query as described here:
http://docs.joomla.org/Selecting_data_using_JDatabase
So yours will look something like this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('user_id') .' AS '. $db->quoteName('name') .' AS '. $db->quoteName('User-Name'));
$query->from($db->quoteName('#__tablename'));
$db->setQuery($query);
$results = $db->loadObjectList();
Please note that I havent tested this query using AS so let me know if it works or not
I've got this to work:
->select($db->quoteName(array('user_id`' . ' AS ' . '`uid', 'name`' . ' AS ' . '`User-Name')))
It's better to use what Joomla! suggest us.
Note by putting 'a' as a second parameter will generate #__content AS a
So, you may have something like this:
$query
->select('*')
->from($db->quoteName('#__content', 'a'))

Laravel query optimization

I have a query in laravel:
...
$query = $model::group_by($model->table().'.'.$model::$key);
$selects = array(DB::raw($model->table().'.'.$model::$key));
...
$rows = $query->distinct()->get($selects);
this works fine and gives me the fields keys' that I need but the problem is that I need to get all the columns and not just the Key.
using this:
$selects = array(DB::raw($model->table().'.'.$model::$key), DB::raw($model->table().'.*'));
is not an option, cuz it's not working with PostgreSQL, so i used $rows to get the rest of columns:
for ($i = 0; $i<count($rows); $i++)
{
$rows[$i] = $model::find($rows[$i]->key);
}
but as you see this is it's so inefficient, so what can i do to make it faster and more efficient?
you can find the whole code here: https://gist.github.com/neo13/5390091
ps. I whould use join but I don't know how?
Just don't pass anything in to get() and it will return all the columns. Also the key is presumably unique in the table so I don't exactly understand why you need to do the group by.
$models = $model::group_by( $model->table() . '.'. $model::$key )->get();

How to order by count in Doctrine 2?

I'm trying to group my entity by a field (year) and do a count of it.
Code:
public function countYear()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('b.year, COUNT(b.id)')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->addOrderBy('sclr1', 'DESC')
->addGroupBy('b.year');
$query = $qb->getQuery();
die($query->getSQL());
$result = $query->execute();
//die(print_r($result));
return $result;
}
I can't seem to say COUNT(b.id) AS count as it gives an error, and
I do not know what to use as the addOrderby(???, 'DESC') value?
There are many bugs and workarounds required to achieve order by expressions as of v2.3.0 or below:
The order by clause does not support expressions, but you can add a field with the expression to the select and order by it. So it's worth repeating that Tjorriemorrie's own solution actually works:
$qb->select('b.year, COUNT(b.id) AS mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
Doctrine chokes on equality (e.g. =, LIKE, IS NULL) in the select expression. For those cases the only solution I have found is to use a subselect or self-join:
$qb->select('b, (SELECT count(t.id) FROM \My\Entity\Album AS t '.
'WHERE t.id=b.id AND b.title LIKE :search) AS isTitleMatch')
->from('\My\Entity\Album', 'b')
->where('b.title LIKE :search')
->andWhere('b.description LIKE :search')
->orderBy('isTitleMatch', 'DESC');
To suppress the additional field from the result, you can declare it AS HIDDEN. This way you can use it in the order by without having it in the result.
$qb->select('b.year, COUNT(b.id) AS HIDDEN mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
what is the error you get when using COUNT(b.id) AS count? it might be because count is a reserved word. try COUNT(b.id) AS idCount, or similar.
alternatively, try $qb->addOrderby('COUNT(b.id)', 'DESC');.
what is your database system (mysql, postgresql, ...)?
If you want your Repository method to return an Entity you cannot use ->select(), but you can use ->addSelect() with a hidden select.
$qb = $this->createQueryBuilder('q')
->addSelect('COUNT(q.id) AS HIDDEN counter')
->orderBy('counter');
$result = $qb->getQuery()->getResult();
$result will be an entity class object.
Please try this code for ci 2 + doctrine 2
$where = " ";
$order_by = " ";
$row = $this->doctrine->em->createQuery("select a from company_group\models\Post a "
.$where." ".$order_by."")
->setMaxResults($data['limit'])
->setFirstResult($data['offset'])
->getResult();`

Resources