how can i nest two AND queries in Doctrine2 using createQueryBuilder? - sql

following is my query :
$em = \Zend_Registry::get('em');
$qb_1 = $em->createQueryBuilder();
$q_1 = $qb_1->select('link_req')
->from('\Entities\link_requests','link_req')
->where( 'link_req.is_confirmed = 1' )
->andWhere('link_req.$link_requestsSenderUser='.$user1_id .'or'.' link_req.$link_requestsSenderUser='.$user2_id)
->andWhere('link_req.$link_requestsReceiverUser='.$user1_id .'or'.' link_req.$link_requestsReceiverUser='.$user2_id);
$result= $q_1->getDql();
echo $result;
and i want following query:
SELECT * FROM [fb_local].[dbo].[link_requests]
WHERE is_confirmed = 1 AND (request_user_id = 12 or request_user_id=19) AND (accept_user_id = 12 or accept_user_id = 19)

Your SQL is just 1 query, so not sure what you're trying to nest. But try the following:
$em = \Zend_Registry::get('em');
$qb_1 = $em->createQueryBuilder();
$q_1 = $qb_1->select('link_req')
->from('\Entities\link_requests','link_req')
->where( 'link_req.is_confirmed = 1' )
->andWhere('link_req.link_requestsSenderUser=:user_id or link_req.link_requestsSenderUser=:user_id')
->andWhere('link_req.link_requestsReceiverUser=:user_id or link_req.link_requestsReceiverUser=:user_id');
$q_1->setParameter('user_id', $user1_id);
$query = $q_1->getQuery();
echo $query->getSql();
Notice how I removed the $ in front of link_requestsReceiverUser. I also made a parameter from $user1_id, this prevents SQL injections.

Related

Laravel Query: implement Eloquent Scope for Query Builder

In the Laravel Query Builder I want to implement something like Scope in Eloquent.
Ref: Laravel Queries: Adding custom feature like Soft Deletes.
I have some complex queries (with joins and what not) but I want to be able to easily apply a WHERE condition that works as follows:
original:
Select * from t1 join t2 ... join t3 ... etc
Where t1.c1 = x OR t3.c4 like "%like"
wanted:
Select * from t1 join t2 ... join t3 ... etc
Where (t1.c1 = x OR t3.c4 like "%like") AND (t1.isTest = false AND t3.isTest = false)
I have written the following method:
public static function scopeNoTest($query, $tables=[false])
{
if (!is_array($tables)) $tables = [$tables];
foreach ($tables as $table)
{
$field = ($table) ? $table . '.isTest' : 'isTest';
$query = $query->where(function ($q) use ($query, $field)
{
$q->where($field, false)
->orWhereNull($field);
}
);
}
return $query;
}
It gets run like this:
$select = <parameter driven select statement>
$where[$role] = <array of different where condition based on passed in parameter?
$bindings = <query bindings based on passed in parameters>
$query = DB::table('Transactions AS trans')
->leftJoin('Buyers AS b', 'trans.ID', '=', 'b.Transactions_ID')
->leftJoin('Sellers AS s', 'trans.ID', '=', 's.Transactions_ID')
->leftJoin('Agents AS ba', 'trans.BuyersAgent_ID', '=', 'ba.ID')
->leftJoin('Agents AS sa', 'trans.SellersAgent_ID', '=', 'sa.ID')
->leftJoin('TransactionCoordinators AS btc', 'trans.BuyersTransactionCoordinators_ID', '=', 'btc.ID')
->leftJoin('TransactionCoordinators AS stc', 'trans.SellersTransactionCoordinators_ID', '=', 'stc.ID')
->leftJoin('lu_UserRoles AS lu_ur', 'trans.ClientRole', '=', 'lu_ur.Value')
->leftJoin('Properties AS p', 'trans.Properties_ID', '=', 'p.ID')
->selectRaw($select);
// ... Adds code to Only Select records with isTest NOT True
$query = Model_Parent::scopeNoTest($query, ['trans', 'ba', 'sa', ]);
$query->whereRaw($where[$role].$whereUser, $bindings)->distinct();
$transactions = $query->get();
The problem with this code is that it does not put the original [passed in] query in parentheses - so the query is wrong!.
The WHERE the code creates is:
where
(`trans`.`isTest` = 0 or `trans`.`isTest` is null)
and (`ba`.`isTest` = 0 or `ba`.`isTest` is null)
and (`sa`.`isTest` = 0 or `sa`.`isTest` is null)
and trans.BuyersTransactionCoordinators_ID = 1 OR trans.SellersTransactionCoordinators_ID = 1
OR trans.CreatedByUsers_ID = 1 OR trans.OwnedByUsers_ID = 1
And I want
where
(`trans`.`isTest` = 0 or `trans`.`isTest` is null)
and (`ba`.`isTest` = 0 or `ba`.`isTest` is null)
and (`sa`.`isTest` = 0 or `sa`.`isTest` is null)
and (trans.BuyersTransactionCoordinators_ID = 1 OR trans.SellersTransactionCoordinators_ID = 1
OR trans.CreatedByUsers_ID = 1 OR trans.OwnedByUsers_ID = 1)
Is there a way to do this ??
It looks like the following line is causing this:
$query->whereRaw($where[$role].$whereUser, $bindings)->distinct();
I think there are two ways to solve this:
// 1
->whereRaw('(' . $where[$role].$whereUser . ')', $bindings)->
// 2
->where(function ($query) use (...) {
$query->whereRaw(...);
})->

How to implement oracle query to select from different tables in laravel

I'm trying to select distinct from different tables in laravel. In oracle I have implemented successfully the query and works. Now I'm trying to "translate" it into laravel. How can I do that?
In oraclesql the query is the following. TEMP table exists as well as all other tables used in this query. Is it possible to do this with DB::raw? Could you give me your advice please?
INSERT INTO TEMP (OBJECT_TYPE, OBLECT_ID)
SELECT DISTINCT HRP1001_CG.OBJECT_TYPE, HRP1001_CG.OBJECT_ID FROM HRP1001_SC, HRP1001_CG, CONFIG
WHERE
(HRP1001_SC.OBJECT_TYPE = 'CG')
AND
(HRP1001_SC.REL_OBJ_TYPE = 'SC')
AND
(HRP1001_SC.REL_OBJ_ID = CONFIG.SC)
AND
((HRP1001_SC.ST_DATE < CONFIG.DES_DATE) AND (HRP1001_SC.END_DATE > CONFIG.DES_DATE))
AND
(HRP1001_CG.REL_OBJ_ID = HRP1001_SC.OBJECT_ID)
AND
((HRP1001_CG.OBJECT_TYPE ='CG') OR (HRP1001_CG.OBJECT_TYPE ='SM'))
ORDER BY HRP1001_CG.OBJECT_ID;
update:
I also tried this code, but no result was received too :(.
$data = DB::table('hrp1001_sc')
->join('config', 'config.sc', '=', 'hrp1001_sc.rel_obj_id')
->join('config', 'config.des_date', '>', 'hrp1001_sc.st_date')
->join('config', 'config.des_date', '<', 'hrp1001_sc.end_date')
->join('hrp1001_cg', 'hrp1001_cg.rel_obj_id', '=',
'hrp1001_sc.object_id')
->where('hrp1001_sc.object_type', '=', 'cg')
->where('hrp1001_sc.rel_obj_type', '=', 'sc')
->select('hrp1001_sc.object_id')
->distinct()
->get();
Solution was found and this is it:
$q = "insert into temp(object_type, object_id)";
$q = $q."select distinct hrp1001_cg.object_type, hrp1001_cg.object_id from
hrp1001_cg, hrp1001_sc, config where";
$q =$q." hrp1001_sc.object_type = 'CG'";
$q = $q." and hrp1001_sc.rel_obj_type = 'SC'";
$q = $q." and hrp1001_sc.rel_obj_id = config.sc";
$q = $q." and hrp1001_sc.st_date < config.des_date";
$q = $q." and hrp1001_sc.end_date > config.des_date";
$q = $q." and hrp1001_cg.rel_obj_id = hrp1001_sc.object_id";
$q = $q." and";
$q = $q." ((hrp1001_cg.object_type = 'CG') or (hrp1001_cg.object_type = 'SM'))";
$xx = DB::insert($q);

Query giving double result instead of single

I have two tables: products and current_product_attribute_values
I have tried a join query to filter them as per attribute selected by the user but when I try this with an additional condition it gives me 2 results instead of one it is including the first one which is not matching as per query:
select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
here is my laravel Controller code :
$all = Input::all();
$q = Input::get('search_text');
$att_val = Input::get('attribute_value');
$subcat = Input::get('subcat_id');
$subcat_name = DB::table('subcategories')->where('id', $subcat)->value('subcategory_name');
$brandname = DB::table('brands')->where('subcat_id', $subcat)->value('brand_name');
$brand_id = DB::table('brands')->where('subcat_id', $subcat)->value('id');
$product_count = DB::table('products')->where('brand_id', $brand_id)->count();
if ($q != "") {
// getting multiple same name params
$query = DB::table('products');
$query->join('current_product_attribute_values', 'products.id', '=', 'current_product_attribute_values.product_id');
$j = 0;
foreach ($all as $key => $values) {
//echo 'my current get key is : ' . urldecode($key). '<br>';
if ($key == $name[$j]) {
$query->where('current_product_attribute_values.attribute_id', '=', $att_id_value[$j]);
echo'<br>';
print_r($query->toSql());
echo'<br>';
//echo '<br> key matched and have some value : <br>';
//echo count($values);
if (count($values) >= 1) {
//echo '<br> it has array inside <br>';
foreach ($values as $val) {
// or waali query in same attribute
echo'<br>';
$query->orwhere('current_product_attribute_values.attribute_value_id', '=', $val);
print_r($query->toSql());
echo'<br>';
}
}
$j++;
}
}
$records = $query->toSql();
$query->where('product_name', 'LIKE', '%' . $q . '%');
$records = $query->toSql();
print_r($records);
$products = $query->paginate(10)->setPath('');
$pagination = $products->appends(array(
'q' => Input::get('q')
));
if (count($products) > 0) {
$filters = DB::table('product_attributes')->where('subcategory_id', $subcat)->get(['attribute_title']);
} else {
$filters = array();
}
$categories = categories::where('add_to_menu', 1)->with('subcategories')->with('brands')->get();
$categoryhome = categories::where('add_to_menu', 1)->with('subcategories')->get();
return view('searchfilter')
->with('productsdata', $products)
->with('filtersdata', $filters)
->with('categories', $categories)
->with('categorieshome', $categoryhome)
->with('subcat_name', $subcat_name)
->with('subcat_id', $subcat)
->with('brandname', $brandname)
->with('product_count', $product_count)
->with('querytext', $q);
}
return 'No Details found. Try to search again !';
its easier if you use raw sql as calling db select function. ex:
$query=DB::select("select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
");
indeed you can concat vars in raw sql if you need to, ex:
$queryBrands = "select id from brands where subcat_id =".$subcat;
//echo $queryBrands
$queryBrands = DB::select($queryBrands);
By looking at your tables, product table with id value 17 has two records in table current_product_attribute_values in column product_id (I assume this column is used as foreign key to product table).
With select *, you select all of the columns from both tables. So it would most likely cause your query to return multiple records.
My suggestions:
Only select the columns you need. Avoid using select * in the long run, i.e. select product.id, product.description, current_product_attribute_values.attribute_values ......
Make use of GROUP BY
Hope these helps.

Zend-Db 2.9 - SQL with RAND order

guys, I need help, I am using zend-db 2.9 - and I have an sql that need the rand() order, but the result of this query came wrong
my code:
$sql = new Sql($this->dbAdapter);
$select = $sql->select(
['a'=>$this->table]
);
$select->order("RAND() ASC");
$select->limit(1);
$stt = $sql->prepareStatementForSqlObject($select);
$res = $stt->execute();
result is :
SELECT `a`.* FROM `mytable` AS `a` ORDER BY `RAND``(``)` ASC LIMIT 1
how to fix it?
I found the answer fot this: Just Add new Expression("RAND()")
$sql = new Sql($this->dbAdapter);
$select = $sql->select(
['a'=>$this->table]
);
$select->order([new Expression("RAND() ASC")]);
$select->limit(1);
$stt = $sql->prepareStatementForSqlObject($select);
$res = $stt->execute();

codeigniter datatables join query not working

//i am using datables in CI but not running properly . please look at the join query and suggests how i can last join condition .
private function _get_datatables_query($term='')
{
$user_id = $this->session->userdata("user_id");
$user_type = $this->session->userdata("user_type");
$column = array('A.type','C.school_name','A.mobile','A.email','A.birthdate','A.anniversary','A.gender','A.firstname','A.lastname');
$this->db->select('A.type,C.school_name,A.mobile,A.email,A.birthdate,A.anniversary,A.gender,A.firstname,A.lastname,C.s2m_admin_id,A.status,A.id,A.pusername');
$this->db->from('users as A');
$this->db->join('school_user as B', 'B.user_id = A.id');
$this->db->join('school as C', 'C.id = B.school_id');
$this->db->join('school as D', 'D.s2m_admin_id = A.id');//<= i am having problem in this line else is working properly .if i add this line query return nothing.
$this->db->having('A.status','active');
$this->db->like('A.type', $term);
$this->db->or_like('A.mobile', $term);
$this->db->or_like('A.firstname', $term);
Try this
$user_id = $this->session->userdata("user_id");
$user_type = $this->session->userdata("user_type");
//$column = array('U.type','S.school_name','U.mobile','U.email','U.birthdate','U.anniversary','U.gender','U.firstname','U.lastname');
$this->db->select(*);
$this->db->from('users as U');
$this->db->join('school_user as SU', 'SU.user_id = U.id');
# added where clause
$this->db->where('school.id = SU.school_id OR school.s2m_admin_id = U.id');
$this->db->having('U.status','active');
$this->db->like('U.type', $term);
$this->db->or_like('U.mobile', $term);
$this->db->or_like('U.firstname', $term);