Codeigniter: how to select_avg of multiple columns - codeigniter

I just started with codeigniter and I'm stuck in my database query. I created a simple survey and I want to get the average of the columns. Right now I'm doing it like this to test it:
for($x=1;$x<=5;$x++){
$this->db->select_avg('q'.$x , 'averageq'.$x);
}
$this->db->where('sex','male');
$query = $this->db->get('survey');
$data = $query->row_array();
print_r($data);
The survey will comprise of 30+ questions, is there a shorter way getting the the average of each column? something like:
select_avg('all columns in my answers table);
thank you

Related

How Query Multiple dataset in Laravel

I am struggling to get list of places that matches current category(multiple dataset) and city:
what i did is the following,
$cat = Category::find($request->category_id)->toArray();
$cat_id = $cat['id'];
and
$places = DB::table('places')
->where('category',$cat_id)
->where('city_id', $request->city_id)
->get();
See screenshot of the dataset:
Data in the database
For your current problem, you can use the LIKE operator.
$places = DB::table('places')
->where('category','LIKE', '%"'.$cat_id.'"%')
->where('city_id', $request->city_id)
->get();
but the above code will not solve your problem permanently. It looks like you are trying to create a many to many relationship in this case the best practice to use pivot tables for this. Better if you could update the schema as an example and follow the Laravel standards to achieve this. Example:
table: category_place , having columns ["category_id", "place_id"]
in the same way, you need to update the following schema
Place Type
table: place_place_type, columns ["place_id", "place_type_id"]
Amenities
table: amenity_place, columns ["amenity_id", "place_id"]
Ref. link: https://laravel.com/docs/8.x/eloquent-relationships#many-to-many-polymorphic-relations

How to get sum along with this Laravel Eloquent query

Database Structure:
Table: sales_payments
columns: id, payer_id, payment_status, amount , ...
Please see this eloquent query. it's working fine but now i need the sum of amount key along with this given eloquent query and where conditions.
$query = SalesPayment::with(['abc.xyz'])
->whereHas('abc.xyz', function ($query) use ($options) {
$query->where('xyz_id',$options['xyz_id']);
});
$query->where(['key3' => key3(), 'payment_status' => PAYMENT_STATUS_SUCCESS]);
$query->orderBy('created_at', 'desc');
return $query->paginate(config('constants.PAGE_LIMIT'));
Possible Solution
Just put a select as mentioned below
$query = SalesPayment::select('*', \DB::raw('SUM(amount) AS total_sale_amount')->with ....
I have tested this solution it's working fine.
Please let me know if there is a better solution than this. And I'm looking for some other solutions Also.
Edit: But there is one problem with this solution that it returning me only one record when i put aggregate function (sum) in select otherwise it was returning more than one records.
You could use the sum method on the query.
$amount = $query->sum('amount');
A new query with the same conditions will be executed to calculate the sum of a column.
https://laravel.com/docs/6.x/queries#aggregates

How to average multiple columns using Eloquent?

I'm looking to get the average value across multiple columns on a related model, something like this:
$this->reviews()->avg('communication', 'friendliness')
Where communication and friendliness are an array of column names. However it appears the aggregate functions only support single column names, so I'm doing this:
$attributes = array('communication', 'friendliness');
$score = array();
foreach ($attributes as $attribute)
{
$score[] = $this->reviews()->avg($attribute);
}
return round(array_sum($score) / sizeof($attributes), 1);
Which results in multiple queries. Any suggestions for a best practice here?
Thanks
To avoid multiple queries you can use a raw database expression within Eloquent as shown below:
$averages = $this->reviews()
->select(DB::raw('avg(communication) c, avg(friendliness) f'))
->first();
echo $averages->c;
echo $averages->f;
Since the aggregate function name avg is recognized by all supported database by Laravel, this will not be a big deal.

How to use like active record for two columns simultaneously

I am trying to make a search page which searches products under the products database using their brands and models. But the problem here is that when a query contains both the brand and model number no results are returned because of the like and ``or_like` active records.
I am trying the following:
$this->db->select("*");
$this->db->from("products");
$this->db->like('brand', $query, 'both');
$this->db->or_like('model', $query, 'both');
$this->db->limit(3);
$this->db->order_by("views", "ASC");
$query = $this->db->get();
What should I do to get results for the queries that contains both the brand and model names?
I'm assuming the actual query looks something like this:
SELECT *
FROM products
WHERE brand LIKE '%query%'
OR model LIKE '%query%'
ORDER BY views ASC
LIMIT 3
That's the correct query to get records where brand contains 'query' or model contains 'query'.
I'd say to run $this->db->last_query(); and see if the query is correct - then run that actual query against your database.

Mulitple LIKE db query using associative array- but all from the same column name...?

I'm trying to query my database using CodeIgniter's active record class. I have a number of blog posts stored in a table. The query is for a search function, which will pull out all the posts that have certain categories assigned to them. So the 'category' column of the table will have a list of all the categories for that post in no particular order, separated by commas, like so: Politics, History, Sociology. etc.
If a user selects, say, Politics, and History, The titles of all the posts that have BOTH these categories should be returned.
So, the list of categories queried will be the array $cats. I thought this would work-
foreach ($cats as $cat){
$this->db->like('categories',$cat);
}
By Producing this:
$this->db->like ('categories','Politics');
$this->db->like ('categories','History');
(Which would produce- 'WHERE categories LIKE '%Politics%' AND categories LIKE '%History%')
But it doesn't work, it seems to only produce the first statement. The problem I guess is that the column name is the same for each of the chained queries. There doesn't seem to be anything in the CI user guide about this (http://codeigniter.com/user_guide/database/active_record.html) as they seem to assume that each chained statement is going to be for a different column name.
Of course it is not possible to use an associative array in one statement as it would have to contain duplicate keys- in this case every key would have to be 'categories'...
With regard to MySQL, I just ran the following query on my database and there were no issues.
SELECT *
FROM `TicketUpdates`
WHERE content LIKE '%update%'
AND content LIKE '%footprints%';
Likewise the following code ran as expected:
$this->db->select('*');
$this->db->from('TicketUpdates');
$this->db->like('content', 'update');
$this->db->like('content', 'footprints');
print_r($this->db->get()->result());
If you're using the 'like' function in CI, you have to prefix and postfix them with the proper query functions, example:
$this->db->select('*');
$this->db->from('tablename');
foreach($cats as $cat){
$this->db->like('categories', $cat);
}
$result = $this->db->get();
you can use following code
$this->db->select("*")->from($table);
foreach($cats as $single_name)
$this->db->or_like("categories",$single_name);
$result = $this->db->get();

Resources