How to use grouby and count using laravel ORM? - mysql

I have an address table where there are many fields like city, ward, tole, district, latitude, longitude. I need to count the number of rows for distinct district. For eg I have following database table as show in screenshot:
I have the rows containing Kathmandu, Bhaktapur and Jhapa as districts. Now I need to get the number of rows containing Kathmandu as district and likewise.
The output should be like this:
array( "Kathmandu"=> 4 , "Bhaktapur" => 1 , "Jhapa"=>1 );
I found multiple solution to the problem in which DB query is used. But I need it ORM way.

You could use aggregated query
$districts = DB::table('address')
->select('district', DB::raw('count(*) as total'))
->groupBy('district')
->pluck('total','district')
->all();

Related

Add multiple count fields of contained model to query in cakephp 3

I want to have in my model, instead of the complete set of entries of the models contained by another one, just the quantity of them. I could do this by adding the "size" field to the resultset, but I'd like to do this in the query, as I want to paginate and order the results dinamically. I am using this code, but for some reason, if the first count is different from zero, both count fields have the same value, which is the value of the second count field.
$query = $this->Users->find('all')
->contain(['Likes','Favs']);
$query
->select(['like_count' => $query->func()->count('Likes.id')])
->leftJoinWith('Likes')
->group(['Users.id'])
->autoFields(true);
$query
->select(['fav_count' => $query->func()->count('Favs.id')])
->leftJoinWith('Favs')
->group(['Users.id'])
->autoFields(true);
$this->paginate['sortWhitelist'] = [
'name',
'email',
'last_login',
'fav_count',
'like_count',
];
I would like to know why this happens and if there is any other way to do what I attempt, which would be to have ('name', email, 'last_login', quantity of entries in Likes with the user's id, quantity of entries in Favs with the user's id). I have tried using join() to do the left join, but I haven't been able to obtain the result I want.
If you have multiple joins, then you need to count with DISTINCT, eg:
COUNT(DISTINCT Likes.id)
This is because your result will contain Likes * Favs number of rows, as for every joined like, all favs will be joined, ie for 2 likes and 10 favs you'd end up with 20 rows in total. A regular COUNT() would include every single one of those rows.
Also note that you don't need to repeat all that grouping, etc stuff, and you can use a callable for select() to avoid breaking up the builder.
$query = $this->Users
->find('all')
->select(function (\Cake\ORM\Query $query) {
return [
'like_count' => $query->func()->count(
$query->func()->distinct(['Likes.id' => 'identifier'])
),
'fav_count' => $query->func()->count(
$query->func()->distinct(['Favs.id' => 'identifier'])
),
];
})
->autoFields(true)
->contain(['Likes', 'Favs'])
->leftJoinWith('Likes')
->leftJoinWith('Favs')
->group(['Users.id']);
Using the functions builder to generate the DISTINCT is a workaround, as there is no API yet that would allow to specifically generate a keyword. The result will be something like DISTINCT(Likes.id), but it will work fine, the parentheses will be interpreted as part of the expression after the keyword, not as part of a function call.

sql query displaying correct values but wrong 'id'

I have an sql query like the following
select *
from register_bs
INNER JOIN spouse_details ON register_bs.reg = spouse_details.reg
WHERE country NOT IN('Australia', 'USA', 'Germany', 'Canada');
This query is displaying correct values for all fields except the 'id' field, it's giving some random id for every data. for example the below data:
when i click on any button of the above data it is going to edit page with different data like below
because the id got is wrong
As there are 900 columns in my register_bs table, I cant use field alias instead of *. Can anyone please tell me how to correct my statement to get the correct id? Thanks in advance
First execute the below query in server and check the values of ID
SELECT register_bs.ID AS ValidateedID, register_bs.*, spouse_details.*
FROM register_bs INNER JOIN spouse_details ON register_bs.reg = spouse_details.reg
WHERE country NOT IN('Australia', 'USA', 'Germany', 'Canada');
Kindly check if the two tables that you have joined have the same column name for their id.
If yes, specify the table first and then the column of the id you want to retrieve.
e.g. register_bs.id

Count a field in database

I want to count a field name 'leave_policy' depending on the name of 'leave_policy' and I am using joins to do it. My database is like this
https://imgur.com/a/gR3Dw
and I want to show count in applied section. For example if I want to count all "Urgent Leaves" and "Paternal Leaves" seperately I have applied till now. https://imgur.com/a/dvjuX
$join = DB::table('leaves_policy')
->join('leaves_policies', 'leaves_policy.leave_policy', '=', 'leaves_policies.title')
->join('leaves_requests', 'leaves_policy.requested_by' , '=', 'leaves_requests.requested_by')
->select('leaves_policy.*', 'leaves_policies.title', 'leaves_policies.total_no_of_leaves_allowed_per_year',
'leaves_policies.no_of_months_leaves_valid', 'leaves_policies.max_leaves_per_month', 'leaves_policies.max_con_leaves_per_month',
'leaves_requests.leave_status', DB::raw('COUNT(leaves_policy.leave_policy) as count'))
->groupBy('id')
->get();
For example,
I have a table Leave_table. leave_policy and purpose are the fields.
I am displaying the leave count based on the leave_policy column. i have used the below query to get the count.
select leave_policy,count(leave_policy) from leave_table group by leave_policy

When i try to display the count value of one column it counts the no. of arrays stored in a single cell of the same row on the same table

I have written the following function to display a table consisting of
recipe name, description, cusine , ........ ..., ingredients AND LIKES.
Everything works fine but the likes column doesnot show the no. of likes bu instead sows the no. of ingredients of the recipe
public function rec(){
$ing = inglist::all();
$rcusine=recipecusine::all();
$rtype=recipetype::all();
$rec = DB::table('recipe_list')
->select('recipe_list.recipe_id','recipe_list.Recipe_name',
'recipe_list.Recipe_desc','recipe_list.Recipe_duration',
DB::raw('group_concat(ing_list.Ing_name separator ",") as recipe_ingredients'),
'recipe_cusine.Cusine_name', 'recipe_type.Recipe_type_name','recipe_list.image',
DB::raw('count(likerecipes.likecount) as likes'))
->join('recipe_inglist', 'recipe_list.recipe_id','=','recipe_inglist.Recipe_id')
->join('ing_list', 'recipe_inglist.Ing_id','=','ing_list.ing_id')
->join('recipe_cusine', 'recipe_list.Recipe_cusine_id','=','recipe_cusine.cusine_id')
->join('recipe_type', 'recipe_list.Recipe_type_id','=','recipe_type.Recipe_typeID')
->join( 'likerecipes', 'recipe_list.recipe_id', '=', 'likerecipes.recipe_id')
->where('recipe_list.recipe_id','>=','1')
->groupBy('recipe_list.recipe_id', 'recipe_list.recipe_name','recipe_list.recipe_desc','recipe_list.recipe_duration', 'recipe_cusine.Cusine_name','recipe_type.Recipe_type_name','recipe_list.image' )->get() ;
/* var_dump($rec);
die();*/
return view('recipe', ['ingredients'=>$ing, 'cusine'=>$rcusine, 'type'=>$rtype,'recipe'=>$rec]);
}
the output i get is
and this is my likerecipes table
can anyone help me where i am wrong.
Because of the joins, your data is duplicated through the records. Since the likerecipes table seems to store like votes casted one by one identified by an id field uniquely, I would count the distinct likerecipes.id values per group:
'count(distinct likerecipes.id) as likes'
I would also introduce the distinct to the group_concat() to make sure that multiple like votes do not make the same ingridients appear multiple times:
'group_concat(distinct ing_list.Ing_name separator ",") as recipe_ingredients'

convert following MySQL query into Codeigniter Active Records

I`m new to codeigniter and I like to convert following MySQL queries into Codeigniter Active Record Queries.
'SELECT name, address, detail, status, startdate, FROM job_step WHERE username = '$_SESSION[username]' and 'status'===0'
P.S- job_step table consists of several columns, but I only need few not the entire table, addition to that information should filter according to session name and status (TINYINT which has 1 and 0).
$this->db->select('name, address, detail, status, startdate')
->from('job_step')
->where(array('username' => $_SESSION['username'], 'status' => 0))
->get()
->result();
This will get you an object. If you want array just change last line to ->result_array();
You can write the above query as:
$this->db->select('name, address, detail, status, startdate');
$this->db->where('username',$_SESSION['username']);
$this->db->where('status','0');
$rset=$this->db->get('job_step');
$result=$rset->result();