multiple where clauses in redbeanphp - php

I'm using readbeanphp as ORM for my php project. I'm trying to load a bean with an additional where clasue. But i'm not sure how to do this.
Normally i'd get a 'bean' like this:
$book = R::load('book', $id);
Which is basically like saying:
SELECT * FROM book WHERE id = '$id'
But i need to add another condition in the where clause:
SELECT * FROM book WHERE id = '$id' AND active = 1
How can i do this with redbeanphp?

R::find() and R::findOne() is what you are looking for:
$beans=R::find("books","active=? AND id=?",array(1,1));
Or if you want a single bean only:
$bean=R::findOne("books","active=? AND id=?",array(1,1));
R::find() will return multiple beans, while R::findOne() returns just a single bean.
You technically could use R::load() but would have to use PHP to check the active field after the bean is loaded to test if it is valid:
$bean=R::load("book",$id);
if($bean->active==1){//valid
//do stuff
}else{//not valid
//return error
}
Hope this helps!

RedBean_Facade::load is using for primary key only.
if you want get beans by a complex query
use
R::find like,
$needles = R::find('needle',' haystack = :haystack
ORDER BY :sortorder',
array( ':sortorder'=>$sortorder, ':haystack'=>$haystack ));
Read more about R::find
http://www.redbeanphp.com/manual/finding_beans
try to use getAll to write your query directly with parameters
R::getAll( 'select * from book where
id= :id AND active = :act',
array(':id'=>$id,':act' => 1) );
Read more about queries,
http://www.redbeanphp.com/manual/queries

these answers are fine but can be simplified. What you should use is:
$book = R::find('books', id =:id AND active =:active, array('id' => $id, 'active' => 1));
And then you can do your standard foreach to loop through the returned array of data.

Related

Add a 2nd condition inside a WHERE clause?

I'm trying to add a second condition inside the WHERE in my foreach loop.
$customers = Customers::find()->where(['status' => 1])->orderBy('vip DESC, id ASC')->all();
Currently, I have it filtering where status=1 but I need to also add where 'rank' does not equal the text "Can".
The reason I need StackOverflow is that I've tried to find the answer on the web but I have a text comparison and a new query method I haven't used before so I can't research well.
How do I add the additional condition in the WHERE clause "AND 'rank' != 'Can'?
If I had to guess at it, I'd write it like this (which likely wrong)
$customers = Customers::find()->where(['status' => 1])
->andwhere (['rank' !=> 'Can'])
->orderBy('vip DESC, id ASC')->all();
According to the amazing ActiveQuery documentation, you have to use andWhere() method:
$customers = Customers::find()->where(['status' => 1])
->andwhere (['not', ['rank' => 'Can']])
->orderBy('vip DESC, id ASC')->all();
OR:
->andwhere (['<>', 'rank', 'Can'])
Please remember, that PHP don't have !=> comparision operator!
In Yii i think you need change andwhere to andWhere.
or try this
$customers = Customers::find()->where("status = 1 and rank!='Can'"])->orderBy('vip DESC, id ASC')->all();

Yii2 query OR condition multiple values for 1 column

I've made an API with the Yii2 framework.
But I don't know how to use the OR condition in my statement.
For example:
I want to get all cars with brand BMW or DODGE.
I've tried the following:
$query = Car::getCar($lang)
->where(['or', ['m.brand' => 'BMW'], ['m.brand' => 'DODGE']])
->all();
But this doesn't work.
I only get it to work with one value for m.brand.
So:
$query = Car::getCar($lang)
->where(['m.brand' => 'BMW'])
->all();
Works just fine.
Tried to put in a few other ways, but I don't get this to work.
Does anyone know what I'm doing wrong?
EDIT
The getCar method returns something like:
(new Query())->select(['a.auto_id'])->from('auto_new a')
EDIT 2
Got it to work with:
$query->andWhere(['or', ['m.brand' => 'BMW'], ['m.brand' => 'DODGE']])
You can actually simplify it a lot by using an array with the values you need:
$query = Car::getCar($lang)
->where(['m.brand' => ['BMW', 'DODGE']])
->all();
This will execute with something like WHERE m.brand IN ('BMW', 'DODGE') which returns the result you are looking for.
If I understand you well, you could use something like this:
Model::find()
->orWhere(['brand' => 'brand1'])
->orWhere(['id' => 'brand2'])
->all();
where() can take an array to create sql along the lines of
SELECT * FROM car WHERE brand in ('brand1', 'brand2');
using this construct you can generate an array of brands you wish to return then use the following ActiveQuery.
$brands = ['BMW', 'DODGE'];
$query = Car::find()->where(['brand' => $brands])->all();

CodeIgniter Join with AND?

I have this CodeIgniter query, which is working almost as intended..
$this->db->select()
->from('user_issues')
->where(array('user_issues.user_id' => $user_id))
->join('issue_properties', 'user_issues.issue_id = issue_properties.issue_id')
->join('series_properties', 'issue_properties.series_id = series_properties.series_id')
->join('user_issues_count', 'user_issues_count.series_id = series_properties.series_id')
->group_by('issue_properties.series_id')
->order_by('series_properties.name')
->offset($offset)->limit($per_page);
}
The query is supposed to return data specific to a users comic collection, the final join is just grabbing the first record it finds that matches, regardless of the user_id.
Is it possible to do something like the AND join in CodeIgniter or a WHERE statement perhaps?
join('user_issues_count', 'user_issues_count.series_id = series_properties.series_id' WHERE 'user_issues_count.user_id = $user_id')
You can add a new where condition wherever it is semantically appropriate in the Active Record Query.
$this->db->select()
->from('user_issues')
->where(array('user_issues.user_id' => $user_id))
->join('issue_properties','user_issues.issue_id = issue_properties.issue_id')
->join('series_properties', 'issue_properties.series_id = series_properties.series_id')
->join('user_issues_count','user_issues_count.series_id = series_properties.series_id')
->where("user_issues_count.user_id = ".$user_id) //new WHERE condition
->group_by('issue_properties.series_id')
->order_by('series_properties.name')
->offset($offset)
->limit($per_page);
The idea is to mix and match the Active Record Functions and print the SQL to see the effect - and tweak them until you get the SQL you require...

get a single value from a table using the query() method inside a model

I have a very complex setup on my tables and achieving this via any of the find() methods is not an option for me, since I would need to fix relationships between my tables and I don't have the time right now, so I'm looking for a simple fix here.
All I want to achieve is run a query like this:
SELECT MAX( id ) as max FROM MyTable WHERE another_field_id = $another_field_id
Then, I need to assign that single id to a variable for later use.
The way I have it now it returns something like [{{max: 16}}], I'm aware I may be able to do some PHP on this result set to get the single value I need, but I was hoping there was already a way to do this on CakePHP.
Assuming you have a model for your table and your are using CakePHP 2.x, do:
$result = $this->MyTable->field('id', array('1=1'), 'id DESC');
This will return a single value.
see Model::field()
This example is directly from the CakePHP documentation. it seems you can use the find method of a model to get count
$total = $this->Article->find('count');
$pending = $this->Article->find('count', array(
'conditions' => array('Article.status' => 'pending')
));
$authors = $this->Article->User->find('count');
$publishedAuthors = $this->Article->find('count', array(
'fields' => 'DISTINCT Article.user_id',
'conditions' => array('Article.status !=' => 'pending')
));

How to set an entity field that does not exist on the table but does exists in the raw SQL as an alias?

Lets say that we have a query like this one:
SELECT *, (CUSTOM_EXPRESSION) as virtualfield FROM users
The user's entity itself has the "virtualfield" but the mapping annotations no, since the table doesn't have this field.
Assuming that it is executed as a raw SQL, how do we populate the entity with the field above?
I've found the answer. To do so, you need to use a scalar value. For instance:
$rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata('Category', 'c');
$rsm->addScalarResult('depth', 'depth');
// [ ... ]
$results = $q->execute();
// Output will be a two-dimensional array
// array(0 => array(0 => CategoryObject, 'depth' => 'scalar-value', // ... ), // ...)
Then, you can loop through it and set the property on the object if you want.
I'm not entirely sure I understand what you are asking. I assume you want to know how to update users.virtualfield with the (CUSTOM_EXPRESSION)? That syntax would be:
update users set virtualfield = (CUSTOM_EXPRESSION)
If you wanted to update all rows.
If I'm off the mark can you please clarify your question?

Categories