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...
Related
I know this same question is already asked before. But I have tried the solution but it's not working for me.
$comp_ids = AllowArea::find()
->select(['comp_code'])
->where(['user_id' => Yii::$app->user->id])
->column();
$ref = (new \yii\db\Query())
->select([
'ProductCode',
'ProductNameFull',
'ProductSpec',
'ProductGroup',
'CompanyCode',
'CompanyName'
,'Price',
'PurchasePrice'
])->from('Product')
->andFilterWhere(['CompanyCode' => $comp_ids])
->all(Yii::$app->sds);
It's giving me empty data.
Flow
The users are assigned areas and some users are assigned areas with a company. So I want the above query to return me the result whether the condition fails or not.
Update 1
The SQL which I am getting is
SELECT `ProductCode`, `ProductNameFull`, `ProductSpec`, `ProductGroup`,
`CompanyCode`, `CompanyName`,
`Price`, `PurchasePrice` FROM `Product` WHERE `CompanyCode` IS NULL
Any help would be highly appreciated.
If nothing works, from what you were told, then you can try:
$ref = (new \yii\db\Query())
->select([
'ProductCode',
'ProductNameFull',
'ProductSpec',
'ProductGroup',
'CompanyCode',
'CompanyName'
,'Price',
'PurchasePrice'
])->from('Product');
if (!empty($comp_ids)) {
$ref->andFilterWhere(['CompanyCode' => $comp_ids]);
}
$ref = $ref->all(Yii::$app->sds);
Try user orFilterWhere() this Adds an additional WHERE condition to the existing one but ignores empty operands.
The new condition and the existing one will be joined using the 'OR' operator.
This method is similar to orWhere(). The main difference is that this method will remove empty query operands. As a result, this method is best suited for building query conditions based on filter values entered by users.
In my application i have product table with 4 different types of filters first step is user selects some filter from frontend then via ajax i push them into session and create a array of each type of filters..below is the code i wrote but it not working as i expected it only return results if there are no empty array passed in where clause but i want to fetch results whatever filter we pass in query
filters array
$industrytags = ['Agriculture & Farming','Medical'];
$styletags = ['Modern','Floral'];
$orientationtags = [];
$colortags = ['red','green'];
Query
$updatedproducts = Product::whereIn('industry', $industrytags)->whereIn('style', $styletags)->whereIn('orientation', $orientationtags)->whereIn('color', $colortags)->get();
its not returning any results because now one of filter type is null but i want a query which fetches data with available filter
Try this -
$condition = "orientation IN ('value1', 'value2', 'value3') OR orientation IS NULL";
$updatedproducts = Product::whereIn('industry', $industrytags)
->whereIn('style', $styletags)
->whereRaw($condition)
->whereIn('color', $colortags)->get();
Hope this will help you.
i am trying to covert this query in active record
SELECT
crm_clients.id,
crm_clients.`moved_date`,
crm_clients.`contractor_id`
FROM
dev_pfands.`crm_clients`
WHERE crm_clients.`contractor_id` = 11
AND (
crm_clients.`status` = 9
OR crm_clients.`status` = 8
OR crm_clients.`status` = 7
)
AND crm_clients.id IN
(SELECT
crm_client_cheques.`client_id`
FROM
dev_pfands.`crm_client_cheques`)
AND crm_clients.`moved_date` BETWEEN '2014-08-01'
AND '2014-11-29 '
AND crm_clients.`contractor_id`<>''
GROUP BY crm_clients.`id
the section I'm having issue is
AND crm_clients.id IN
(SELECT
crm_client_cheques.client_id
FROM
dev_pfands.crm_client_cheques) `
i've tried the where_in method but overtime i try to include my attempt of $this ->db_pfands -> where('crm_client_cheques.client id' ,'id'); get hit with errors and have no idea how to get past this.
the original query should return 703 rows and when I've removed the part I'm stuck with it increase to 3045 so i need it to be included. any help is appreciated.
First of all you have a error in your code.
$this->db_pfands->where('crm_client_cheques.client id', 'id');
This will be
$this->db_pfands->where('crm_client_cheques.client_id', 'id');
You have to provide the right column name and as far i know database's column name have not contain any space.
Now I think this active record query will help you to get your result.
$query = $this->db->select('crm_clients.id, crm_clients.moved_date, crm_clients.contractor_id')
->where('moved_date BETWEEN "2014-08-01" AND "2014-11-29"')
->where('contractor_id', 'id')
->where_in('status', [9,8,7])
->from('crm_clients')
->join('crm_client_cheques', 'crm_client_cheques.client_id = crm_clients.id')
->group_by('id')
->get();
$result = $query->result();
May be you have change couple of names because they are in different database, but i believe you can do it.
I have an itemid and a category id that are both conditional. If none is given then all items are shown newest fist. If itemid is given then only items with an id lower than given id are shown (for paging). If category id is given than only items in a certain category are shown and if both are given than only items from a certain category where item id smaller than itemid are shown (items by category next page).
Because the parameters are conditional you get a lot of if statements depending on the params when building a SQL string (pseudo code I'm wearing out my dollar sign with php stuff):
if itemid ' where i.iid < :itemid '
if catid
if itemid
' and c.id = :catid'
else
' where c.id = :catid'
end if
end if
If more optional parameters are given this will turn very messy so I thought I'd give the createQueryBuilder a try. Was hoping for something like this:
if($itemId!==false){
$qb->where("i.id < :id");
}
if($categoryId!==false){
$qb->where("c.id = :catID");
}
This is sadly not so and the last where will overwrite the first one
What I came up with is this (in Symfony2):
private function getItems($itemId,$categoryId){
$qb=$this->getDoctrine()->getRepository('mrBundle:Item')
->createQueryBuilder('i');
$arr=array();
$qb->innerJoin('i.categories', 'c', null, null);
$itemIdWhere=null;
$categoryIdWhere=null;
if($itemId!==false){
$itemIdWhere=("i.id < :id");
}
if($categoryId!==false){
$categoryIdWhere=("c.id = :catID");
}
if($itemId!==false||$categoryId!==false){
$qb->where($itemIdWhere,$categoryIdWhere);
}
if($itemId!==false){
$qb->setParameter(':id', $itemId);
}
if($categoryId!==false){
$arr[]=("c.id = :catID");
$qb->setParameter(':catID', $categoryId);
}
$qb->add("orderBy", "i.id DESC")
->setFirstResult( 0 )
->setMaxResults( 31 );
I'm not fully trusting the $qb->where(null,null) although it is currently not creating errors or unexpected results. It looks like these parameters are ignored. Could not find anything in the documentation but an empty string would generate an error $qb->where('','').
It also looks a bit clunky to me still, if I could use multiple $qb->where(condition) then only one if statement per optional would be needed $qb->where(condition)->setParameter(':name', $val);
So the question is: Is there a better way?
I guess if doctrine had a function to escape strings I can get rid of the second if statement round (not sure if malicious user could POST something in a different character set that would allow sql injection):
private function getItems($itemId,$categoryId){
$qb=$this->getDoctrine()->getRepository('mrBundle:Item')
->createQueryBuilder('i');
$arr=array();
$qb->innerJoin('i.categories', 'c', null, null);
$itemIdWhere=null;
$categoryIdWhere=null;
if($itemId!==false){
$itemIdWhere=("i.id < ".
someDoctrineEscapeFunction($id));
}
Thank you for reading this far and hope you can enlighten me.
[UPDATE]
I am currently using a dummy where statement so any additional conditional statements can be added with andWhere:
$qb->where('1=1');// adding a dummy where
if($itemId!==false){
$qb->andWhere("i.id < :id")
->setParameter(':id',$itemId);
}
if($categoryId!==false){
$qb->andWhere("c.id = :catID")
->setParameter(':catID',$categoryId);
}
You can create filters if you want to use more generic approach of handling this.
Doctrine 2.2 features a filter system that allows the developer to add SQL to the conditional clauses of queries
Read more about filters however, I'm handling this in similar manner as you showed
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.