Laravel ORM select and whereBetween - php

I have next code:
$properties = $properties
->selectRaw('*,'. $this->userCurrency->c_rate .' / c_rate * p_fixed_price AS
converted_p_fixed_price');
after that I want to sort by this price.
$properties = $properties->whereBetween('converted_p_fixed_price',
[$request->low_price ,$request->hight_price]
);
But in result i got Column not found: 1054
Please help, how to whereBetween that field in right way?

As referred Here :An alias can be used in a query select list to give a column a different name. You can use the alias in GROUP BY, ORDER BY, or HAVING clauses to refer to the column, Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined, so you must use having instead of whereBetween.
The second part of your code can be something like this:
$properties = $properties
->having('converted_p_fixed_price', '>=', $request->low_price)
->having('converted_p_fixed_price', '<=' ,$request->hight_price);
As you can not use pagination with having clauses in Laravel, if you want to paginate results, you can use something like this:
$properties = $properties
->whereRaw($this->userCurrency->c_rate . ' / c_rate * p_fixed_price >= ' . $request->low_price)
->whereRaw($this->userCurrency->c_rate . ' / c_rate * p_fixed_price <= ' . $request->hight_price)
->paginate($page_length);

Related

Laravel using eloquent Count with Having

I have two variables $customers (that holds all the rows) and $total that holds the total rows of the query.
I usually do the following query:
$customers = Customers::select
(
'customer.id',
'customer.name',
'customer.min_tolerance',
DB::raw('(SELECT MAX(tolerance) FROM customers_tolerances WHERE customer_id = customer.id) AS tolerance')
)
->from('customers AS customer')
->whereIn('customer.id', $request->customers);
$total = $customers->count();
$customers = $customers->limit($request->limit)
->offset($request->offset)
->get();
This works great. I get all the rows limited (usually 20 per page) plus the total rows.
My problem is that I added a having clause to my query, so it looks like this now:
$customers = Customers::select
(
'customer.id',
'customer.name',
'customer.min_tolerance',
DB::raw('(SELECT MAX(tolerance) FROM customers_tolerances WHERE customer_id = customer.id) AS tolerance')
)
->from('customers AS customer')
->whereIn('customer.id', $request->customers)
->havingRaw('tolerance >= customer.min_tolerance');
And the $count stopped working as it triggers an error:
Column not found: 1054 Unknown column 'tolerance' in 'having clause'
select count(*) as aggregate from customers as customer having tolerance >= customer.min_tolerance)
So how can I use count with having clause?
Solved.
Before creating this post I tried to create a subquery, as follow:
SELECT COUNT(*) FROM (SELECT ...)
But the slowness of the query was too much, so I tried to look for answers here. The slowness was due to the lack of index in tables.
By adding ALTER TABLE customers_tolerances ADD INDEX(customer_id); I'm now able to retrieve fast the total results.

Use concatenated columns in query with Eloquent

I am creating an api to search users. I am doing this in Eloquent, and I am wondering if there is any way to create a query with Eloquent like this:
SELECT * FROM users WHERE CONCAT('first_name', ' ', 'last_name') LIKE '%searchstring%' OR email LIKE '%searchstring%';
Is there a way to do this with the Eloquent query builder?
What I would like to do is essentially this:
$users = User::where('CONCAT(first_name, " ",last_name)', 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);
This results in Column not found: 1054 Unknown column 'CONCAT(first_name," ",last_name)' in 'where clause'
I was able to find the answer to this question, and the solution was to use the DB::raw method around the column name.
The working solution looks like this:
$users = User::where(DB::raw('CONCAT(first_name, " ",last_name)'), 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);
Try this:
$users = User::where(\DB::raw('CONCAT(first_name, " ",last_name)'), 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);

using SUM in whereraw/where in laravel framework

I have columns named as PlanCost Discount AmountPaid and a label which contains the Due
Here,I am trying to display only the rows where the PlanCost != AmountPaid
this is my whole query
$getID = isset($inputArray['id']) ? $inputArray['id'] : 0;
$query = TelePlanSelect::join('tele_plan', 'tele_plan.id', '=', 'tele_plan_select.teleplan_id' )
->leftjoin('tele_payment_defs', 'tele_payment_defs.telereg_id', '=', 'tele_plan_select.telereg_id')
->leftjoin('tele_payment_items', function ($join){
$join->on('tele_payment_items.telepaymentdefs_id', '=', 'tele_payment_defs.id')
->on('tele_payment_items.teleplan_id', '=' ,'tele_plan.id');
} )
->selectRaw('tele_plan.id as `PlanID`,' .
'tele_plan.plan_name as `PlanName`,' .
'tele_plan.plan_cost as `PlanCost`,' .
'tele_plan.plan_details as `PlanDetails`,'.
'sum(tele_payment_items.amount) as `AmountPaid` ,'.
'COALESCE(sum(tele_payment_items.discount),0) as `Discount`,'.
'(COALESCE(tele_plan.plan_cost,0) - sum(COALESCE(tele_payment_items.discount,0))) - sum(coalesce(tele_payment_items.amount, 0)) as `Due` '
)
->where('tele_plan_select.telereg_id', $getID)
->groupBy('tele_plan.id')
->where(' tele_plan.plan_cost', '!=', 'sum(tele_payment_items.amount)');
I am not sure whether we can use sum in where/whereraw
Could someone help me?
EDIT 1 :
{"message":"SQLSTATE[HY000]: General error: 1111 Invalid use of group function (SQL: select count(*) as aggregate from (select tele_plan.id asPlanID,tele_plan.plan_name asPlanName,tele_plan.plan_cost asPlanCost,tele_plan.plan_details asPlanDetails,sum(tele_payment_items.amount) asAmountPaid,COALESCE(sum(tele_payment_items.discount),0) asDiscount,(COALESCE(tele_plan.plan_cost,0) - sum(COALESCE(tele_payment_items.discount,0))) - sum(coalesce(tele_payment_items.amount, 0)) asDuefromtele_plan_selectinner jointele_planontele_plan.id=tele_plan_select.teleplan_idleft jointele_payment_defsontele_payment_defs.telereg_id=tele_plan_select.telereg_idleft jointele_payment_itemsontele_payment_items.telepaymentdefs_id=tele_payment_defs.idandtele_payment_items.teleplan_id=tele_plan.idwheretele_plan_select.telereg_id= 8 and tele_plan.plan_cost <> sum(tele_payment_items.amount) group bytele_plan.id) as a) # C:\\xampp\\htdocs\\halframework\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:625","status":"failed"}
You can use raw sql functions like sum, but you have to wrap them in laravel's \DB::raw() function so they won't be escaped.
For your Where clause, you should do the following
->where('tele_plan.plan_cost', '<>', \DB::raw('sum(tele_payment_items.amount)'));
You could also use laravel's WhereRaw function to write your own conditions:
->whereRaw('tele_plan.plan_cost <> sum(tele_payment_items.amount)')
Update:
The error stated that there was a problem with the GroupBy. The reason for this is because a sum can only be done after a group by, but a where can't. So, this will have to be added in a HAVING clause.
Replace the where by a having, and this should work:
->havingRaw('tele_plan.plan_cost <> sum(tele_payment_items.amount)');

Column not found:1054 error even though the column is defined in laravel

SQLSTATE[42S22]: Column not found: 1054 Unknown column
'vpc_order_info' in 'where clause' (SQL: select `sequa_transaction_id`
as `vpc_transaction_no`, `merchant_order_id` as `vpc_order_info`,
`date_created` as `yesterday`, `card_number` as `vpc_Card`, `amount`
as `vpc_Amount`, `authorization_code` as `vpc_authorizeId` from
`ipg_sentry_response` where `merchant_id` = 12136901 and
`vpc_order_info` like %-% and `response_code` = 1 and `date_created`
between 2016-03-22 and 2016-09-31)
I am getting this error message though I have defined the column as given below.
$col = array("sequa_transaction_id as vpc_transaction_no","merchant_order_id as vpc_order_info","date_created as yesterday","card_number as vpc_Card", "amount as vpc_Amount","authorization_code as vpc_authorizeId");
$records = DB::table('ipg_sentry_response')->select($col)
->where('merchant_id', '=', $vpc_Merchant)
->where('vpc_order_info' ,'like', "%-%")
->where('response_code', '=', '1')
->whereBetween('date_created', array($date,$date2))
//->whereBetween('date_created', array($date,$date2))
->get();
Can anyone please help me with it? I am using Laravel version 5.2.
The column alias is defined but it is not available to be used in where caluse yet. You can use alias in group, order... you need to use the column name instead of the alias. Try -
$col = array("sequa_transaction_id as vpc_transaction_no",
"merchant_order_id as vpc_order_info","date_created as yesterday",
"card_number as vpc_Card", "amount as vpc_Amount",
"authorization_code as vpc_authorizeId");
$records = DB::table('ipg_sentry_response')->select($col)
->where('merchant_id', '=', $vpc_Merchant)
->where('merchant_order_id' ,'like', "%-%")
->where('response_code', '=', '1')
->whereBetween('date_created', array($date,$date2))
->get();
You can only use column aliases in GROUP BY, ORDER BY, or HAVING clauses. Standard SQL doesn't allow you to refer to a column alias in a WHERE clause.
As what stated by the answer above mine, the WHERE clause doesn't accept aliases. Furthermore, you may also use the GROUP BY - HAVING methods (https://laravel.com/docs/5.3/queries#ordering-grouping-limit-and-offset)

how to use logical operators between two columns of different tables in codeigniter?

How do I use logical operators between two columns of different tables in CI?
I have to check a condition like:
$this->db->select('tbl.id ')
->from('tbl')
->join('table','tbl.company_id = table.company_id')
->where('tbl.maxprice >=table.maxprice')
->where('tbl.minprice <= table.minprice')
->order_by('tbl.date')
->get()
->row_array();
It shows an error: unknown column table.maxprice.
How can I solve this issue? Thanks.
If your table name is really table then you should not use because some keywords are reserved vendor specific and table is a reserved keyword ,for now you can rewrite your query as below
$this->db->select('t.id ')
->from('tbl t')
->join('table t1', 't.company_id = t1.company_id') /* best is to change your table name from table to something else */
->where('t.maxprice >= t1.maxprice')
->where('t.minprice <= t1.minprice')
->order_by('t.date')
->get()
->row_array();
like that
$this->db->select('tb.id ')
->from('tbl tb')
->join('table','tb.company_id = table.company_id')
->where('tb.maxprice >=table.maxprice')
->where('tb.minprice <= table.minprice')
->order_by('tbl.date')
->get()
->row_array();

Categories