I get Error in laravel query when i use count(rating) as productRating then it not found productRating Field - sql

I join My product table to review table then i count the rating of product then put condityion on rating then i got error that field not found.
Code:
$products = Product::leftjoin('reviews','products.id','=','reviews.productID')
->select('products.*',DB::raw("AVG(rating) as 'productRating'"))
->where('products.status','=',"enable")
->where(function($query) use ($categoriesID,$brands,$priceArray,$ratingArray)
{
$query->whereIn('categoryID',$categoriesID);
if(count($brands) > 0)
{
$query->whereIn('brandID',$brands);
}
$query->whereBetween('productSellingPrice',$priceArray);
if(count($ratingArray) > 0)
{
$query->whereBetween('productRating',$ratingArray);
}
})
->groupBy('products.id')
->get();
Error :
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'productRating' in 'where clause' (SQL: select `products`.*, AVG(rating) as 'productRating' from `products` left join `reviews` on `products`.`id` = `reviews`.`productID` where `products`.`status` = enable and (`categoryID` in (1, 3, 4, 8, 9, 11, 18, 21, 28, 31) and `productSellingPrice` between 50 and 5000 and `productRating` between 4 and 5) group by `products`.`id`)

This is SQL, not laravel, error.
You can not use aggregated field is where clause, you need to use having instead.
$products = Product::leftjoin('reviews','products.id','=','reviews.productID')
->select('products.*',DB::raw("AVG(rating) as 'productRating'"))
->where('products.status','=',"enable")
->whereIn('categoryID',$categoriesID)
->whereBetween('productSellingPrice',$priceArray)
->groupBy('products.id');
if(count($brands) > 0)
{
$products->whereIn('brandID',$brands);
}
if(count($ratingArray) > 0)
{
// assume $ratingArray = [$min, $max];
list($ratingMin, $ratingMax) = $ratingArray;
$products->having('productRating', '>', $ratingMin);
$products->having('productRating', '<', $ratingMax);
}
$items = $products->get();

thank you Everyone i already solved it
Code:
$products = Product::leftjoin('reviews','products.id','=','reviews.productID')
->select('products.*',DB::raw("IFNULL(AVG(rating),0) as 'productRating'"))
->where('products.status','=',"enable")
->where(function($query) use ($categoriesID,$brands,$priceArray)
{
$query->whereIn('categoryID',$categoriesID);
if(count($brands) > 0)
{
$query->whereIn('brandID',$brands);
}
$query->whereBetween('productSellingPrice',$priceArray);
})
->groupBy('products.id')
->having('productRating', '>=', $startRating)
->having('productRating', '<=', $endRating)
->get();

Related

How to convert SQL to LINQ where it contains IN keyword in statement

I have got this SQL statement which I am trying to convert to LINQ.
SELECT *
FROM History
WHERE Status = 'Created' AND HistoryId IN (1, 2, 3);
I have not been able to do the IN part. Tried following but I am unable to complete it:
var list = new List<int>() { 1, 2, 3};
var result = db.History.Where(x => x.Status == 'Created' && )
How do I write IN part of SQL in LINQ?
You can use Contains:
var result = db.History.Where(x => x.Status == 'Created' && list.Contains(x.HistoryId))

Column not found: 1054 Unknown column '2' in 'on clause' - InnerJoin query not working properly

I am trying to execute the following code, the error applies to the $waitingToBeShipped... section of the code. As you can see I am using an innerJoin. I want to retrieve all of the rows that have orders containing products that are still waiting to be shipped.
public function destroyMany($ids) {
$status = false;
$ids = explode(",", $ids);
foreach ($ids as $id) {
$innerJoin = OrderDetails::where('product_id', $id)->pluck('order_id');
if ($innerJoin->count()) {
$innerJoin = preg_replace("/[^A-Za-z0-9\-]/", '', $innerJoin);
Log::info($innerJoin);
}
$waitingToBeShipped = Order::where('is_delivered', 0)
->join('order_details', 'orders.id', '=', $innerJoin)
->get();
}
}
But it returns:
local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column '2' in 'on clause' (SQL: select * from `orders` inner join `order_details` on `orders`.`id` = `2` where `is_delivered` = 0 and `orders`.`deleted_at` is null)
I've tried to run this query manually in PHPMyAdmin, which also gives an error with the literal query that I just copied, BUT, when I remove the backticks around the number 2, it does actually give me a result.
I am not sure how I can do the same for my code? Any help would be appreciated, thanks!
The fix to this is to change the query to:
public function destroyMany($ids) {
$status = false;
$ids = explode(",", $ids);
foreach ($ids as $id) {
$innerJoin = OrderDetails::where('product_id', $id)->pluck('order_id');
if ($innerJoin->count()) {
$innerJoin = preg_replace("/[^A-Za-z0-9\-]/", '', $innerJoin);
Log::info($innerJoin);
}
$waitingToBeShipped = Order::where('is_delivered', 0)
->join('order_details', 'orders.id', '=', 'order_details.order_id')
->where('order_details.order_id', $innerJoin)
->get();
}
}

Laravel/SQL: where column Equals NOT and NULL

LARAVEL 5.4 (but probably it's a more general SQL question)
Hello! I have a table with a structure:
Suppose it's my model 'Table'.
I want a query which:
uses (receives) variables :
$id of array ['id', 'string', integer]
where string is '<' or '>'
$status_not_bad = bool;
(if true - include all rows where 'status' !== 'bad' AND 'status' IS NULL);
for example, we are given:
$id = [['id', '>', 0]];
$status_not_bad = true;
Table::thisquery() ... ->get();
"get rows where status is not bad and id > 0" returns rows 1 and 3.
but if we given:
$id = [['id', '<', 3]];
$status_not_bad = true;
Table::thisquery() ... ->get();
"get rows where status is not bad and id < 3" returns row 1
(it should be same query which return those results using those variables).
Probably you end with something like this:
if ($status_not_bad) {
$nStatus = 'bad';
} else {
$nStatus = 'good';
}
Table::thisquery()->where('status', '<>', $nStatus)
->whereNotNull('status')
->where($id[0], $id[1], $id[2])
->get();
But it would be a good idea to check $id keys first.
Since row id = 3 you need <= in your where statement to have that row included in the result set
$id = ['id', '<=', 3];
So, I this works:
$chain = Sample::when($status_not_bad, function($query){
return $query->where('status', '<>', 'bad')
->orwhereNull('status');
})
->where([$id])
->get();

Laravel 5 Eloquent where and or in Clauses

i try to get results from table with multiple where and/or clauses.
My SQL statement is:
SELECT * FROM tbl
WHERE m__Id = 46
AND
t_Id = 2
AND
(Cab = 2 OR Cab = 4)
How i can get this with Laravel Eloquent?
My Code in Laravel is:
$BType = CabRes::where('m_Id', '=', '46')
->where('t_Id', '=', '2')
->where('Cab', '2')
->orWhere('Cab', '=', '4')
->get();
Using advanced wheres:
CabRes::where('m__Id', 46)
->where('t_Id', 2)
->where(function($q) {
$q->where('Cab', 2)
->orWhere('Cab', 4);
})
->get();
Or, even better, using whereIn():
CabRes::where('m__Id', 46)
->where('t_Id', 2)
->whereIn('Cab', $cabIds)
->get();
Also, if you have a variable,
CabRes::where('m_Id', 46)
->where('t_Id', 2)
->where(function($q) use ($variable){
$q->where('Cab', 2)
->orWhere('Cab', $variable);
})
->get();
When we use multiple and (where) condition with last (where + or where) the where condition fails most of the time. for that we can use the nested where function with parameters passing in that.
$feedsql = DB::table('feeds as t1')
->leftjoin('groups as t2', 't1.groups_id', '=', 't2.id')
->where('t2.status', 1)
->whereRaw("t1.published_on <= NOW()")
>whereIn('t1.groupid', $group_ids)
->where(function($q)use ($userid) {
$q->where('t2.contact_users_id', $userid)
->orWhere('t1.users_id', $userid);
})
->orderBy('t1.published_on', 'desc')->get();
The above query validate all where condition then finally checks
where t2.status=1 and
(where t2.contact_users_id='$userid' or where t1.users_id='$userid')

Conditions in JOINed tables shows error CakePHP

I have two tables employee_personals where all the personal record of the employee is stored and telephone_bills where the telephone bills paid to a particular employee is stored for each month. Now in my employeePersonalsController.php I have a function called api_show_employees() which is similar to below :
function api_show_employees() {
//$this->autoRender = false;
//Configure::write("debug",0);
$office_id = '';
$cond = '';
if(isset($_GET['office_id']) && trim($_GET['office_id']) != '') {
$office_id = $_GET['office_id'];
$cond['EmployeePersonal.office_id'] = $office_id;
}
if(isset($_GET['telephoneBillTo']) && isset($_GET['telephoneBillFrom']) ) {
if($_GET['telephoneBillTo'] != '' && $_GET['telephoneBillFrom'] != '') {
$cond['TelephoneBill.bill_from'] = $_GET['telephoneBillFrom'];
$cond['TelephoneBill.bill_to'] = $_GET['telephoneBillTo'];
}
}
$order = 'EmployeePersonal.name';
// $employee = $this->EmployeePersonal->find('all');
$employee = $this->EmployeePersonal->find('all',array('order' => $order,'conditions'=>$cond));
//return json_encode($employee);
}
This functions basically finds all the employees who paid bills in the given period. But I am getting an error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'TelephoneBill.bill_from' in 'where clause'
Models : EmployeePersonal.php:
var $hasMany = array(
'TelephoneBill' => array(
'className' => 'TelephoneBill',
)
);
TelephoneBill.php
public $name = 'TelephoneBill';
var $hasMany = array('EmployeePersonal');
NB: If I skip the bill_from and bill_to conditions, I am getting the results , with TelephoneBill array !
TLDR: use Joins instead.
Details/Notes:
1) it looks like you're using recursive. Don't do that. Use Containable instead.
2) You can't limit the parent model based on conditions against data from a contained/recursive-included table - instead, use Joins.
2b) Or, you could query from the other direction, and query your TelephoneBill with conditions, then contain the EmployeePersonal.