How to count specific table column using laravel - laravel

I have here a laravel query:
DB::table('notifications')
->leftJoin('domains', 'domains.domain', '=', 'notifications.data->via_domain')
->select('notifications.data->via_domain as domain_name')
->groupBy('notifications.data->via_domain')
->get();
This shows domain names that exists between the tables 'notifications' and 'domains'. However, I want to count notifications.notifiable_id field in 'notifications' by:
DB::table('notifications')
->leftJoin('domains', 'domains.domain', '=', 'notifications.data->via_domain')
->selectRaw('count(notifications.notifiable_id), notifications.data->via_domain')
->get();
However it shows error in SQL syntax.
(You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near
via_domain from notifications left join domains on
domains.domain = not at line 1 (SQL: select
count(notifications.notifiable_id), notifications.data->via_domain
from notifications left join domains on domains.domain =
notifications.data->'$."via_domain"')')
Thanks for the help, minna-san.

I already got it!
Here's my code:
DB::table('notifications')->leftJoin('domains', 'domains.domain', '=', 'notifications.data->via_domain')
->select('notifications.data->via_domain as domainName', DB::raw('COUNT(notifications.notifiable_id) AS leadsCount'))
->groupBy('notifications.data->via_domain')
->get();
This results to an array showing the domain name and its leadsCount.
Thanks everyone.

for example, assume we have data as like below
Couponview::whereBetween('created_at', [$start_date, $end_date])
->select('store_id', DB::raw('COUNT(store_id) as store_count'))
->groupBy('store_id')
->orderBy(DB::raw('COUNT(store_id)'), 'DESC')
->take(8)
->get();
then We got OutPut Like below example image

Related

Select joined table with same column name but different value using eloquent

I'm trying to call 2 columns from 2 different tables. applicants.ic_no and agents.ic_no. It have different values.
Using the following codes only displayed only ic_no from agents.ic_no
$claimLists = ClaimDetail::join('applicants', 'applicants.ic_no', '=', 'claim_details.ic_no')
->join('agents', 'agents.id', '=', 'claim_details.agent_id')
->where('claim_date', $cutt_off)
->groupBy('agents.id', 'claim_details.id', 'applicants.id')
->orderBy('agents.id')
->orderby('amount', 'desc')
->get();
How do i get both columns to display?
This is because, you have ic_no in both tables. By default MYSQL picks one of it to display, it is the same as having id in both tables and from your results, how would you know which table's ic_no you are accessing while they have the same name?
Alternatively you can use select and DB::raw to change the name of one of the ic_no fields, and similiarly for any other similiar fields. For example;
$claimLists = ClaimDetail::join('applicants', 'applicants.ic_no', '=', 'claim_details.ic_no')
->join('agents', 'agents.id', '=', 'claim_details.agent_id')
->select('claim_details.*', DB::raw('agents.ic_no as agents_ic_no'), 'agents.XXX', 'agents.YYYY', 'applicants.XXX')
->where('claim_date', $cutt_off)
->groupBy('agents.id', 'claim_details.id', 'applicants.id')
->orderBy('agents.id')
->orderby('amount', 'desc')
->get();
instead of XXX and YYY, you can put the fields that you would like to get and you can get as many as you want or remove them, if you don't want to get any field from the second table, but the main thing here is you are access the agents.ic_no as agents_ic_no or whatever name you would like to give it.
I solve this issue by adding select to rename the conflict column name. So this is the code:
$processed = ClaimDetail::join('applicants', 'applicants.ic_no', '=', 'claim_details.ic_no')
->join('agents', 'agents.id', '=', 'claim_details.agent_id')
->select('*')
->selectRaw('applicants.ic_no as nokp, agents.ic_no as agic')
->where('claim_details.agent_id',$agent->id)
->orderBy('claim_details.claimable', 'desc')
->orderby('claim_details.amount', 'desc')
->get();
Thanks guys for your time.

How to count two related tables using Laravel Query Builder?

I have two tables in my database
My first table
And my second table
I would like to count how many gold members exists and how many silver members exists... I want to do a single count for each category... The rif can be repeated in the column but is the key to join the two tables.. I'm working with Query Builder and I would like to continue work with that. Someone can help me?
I tried with this code but didn't work
$count = DB::table('table1')
->join('table2', 'table1.rif', '=', 'table2.rif')
->select(DB::raw('category')
->count();
Try this:
use Illuminate\Support\Facades\DB;
DB::table('table2')
->join('table1', 'table2.rif', '=', 'table1.rif')
->select(DB::raw('count(*) as count'), 'table1.category as category')
->groupBy('category')
->get();
If you want to count only a specific category:
DB::table('table2')
->join('table1', 'table2.rif', '=', 'table1.rif')
->where('table1.category', 'Silver')
->count()
See Laravel docs for more info.

Pagination creates an error

Im trying to paginate a search to bring back pages of 18 items. Previously i had this code working code:
$productsQuery = Product::where('approved', '=', 1)->leftJoin('reviews', 'reviews.products_id', '=', 'products.id')->select('products.*', DB::raw('AVG(ratings) as ratings_average' ))->groupBy('id')->orderBy('ratings_average', 'DESC');
I add on paginate to this as shown in the docs
$productsQuery = Product::where('approved', '=', 1)->leftJoin('reviews', 'reviews.products_id', '=', 'products.id')->select('products.*', DB::raw('AVG(ratings) as ratings_average' ))->groupBy('id')->orderBy('ratings_average', 'DESC')->paginate(18);
And get an error
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in group statement is ambiguous
Any ideas on how to paginate the statement?
It's not neccesarily the pagination which is causing the issue, the error is caused by your group by.
You should place the table name / alias name prior to the id EG:
$productsQuery = Product::where('approved', '=', 1)->leftJoin('reviews', 'reviews.products_id', '=', 'products.id')->select('products.*', DB::raw('AVG(ratings) as ratings_average' ))->groupBy('product.id OR reviews.id')->orderBy('ratings_average', 'DESC');
Please see the ammended statement above, note that copy pasting it won't work, you'll see to change that groupby argument.
You should also visit the docs on Eloquent, you have approached this in a way where you're fighting laravel. I would suggest getting a tighter grip on the ORM used.
Good luck!
The error is pretty self explanatory here:
Column 'id' in group statement is ambiguous
so you need to make
`groupBy('id')`
more explicit, by telling which id (from which table, as each table used in your query features id column) you want to be used for grouping.

Laravel Order by in one to many relation with second table column

Hi i have tables with one to many relation
sectors
id
name
position
seat_plans
id
name
sector_id
I just want to select all seat plans order by sectors.position. I tried
$seat_plans = SeatPlan::with(['sector' => function($q){
$q->orderBy('position');
}
])->get();
but it is not working. when i check The SQL it is generating query like
select * from seat_plans
can anybody please tell me how to do this?
I don't think you need a custom function for your use case. Instead try this:
$users = DB::table('seat_plans')
->join('sectors', 'seat_plans.sector_id, '=', 'sectors.id')
->select('seat_plans.*')
->orderBy('sectors.position')
->get();

Laravel Eloquent orWherePivot Not Returning Expected Result

I have an eloquent query where I am not getting the expected results and I was hoping someone could explain to me what the correct way to write the query.
I have three tables:
records (belongsToMany users)
users (belongsToMany records)
record_user (pivot)
The record_user table also has a column for role.
I attempt to get all the records where the user has the role of either singer or songwriter:
$results = User::find(Auth::user()->id)
->records()
->wherePivot('role', 'singer')
->orWherePivot('role', 'songwriter')
->get();
Below is how the SQL syntax is generated:
select `records`.*, `record_user`.`user_id` as `pivot_user_id`,
`record_user`.`record_id` as `pivot_record_id` from `records`
inner join `record_user` on `records`.`id` = `record_user`.`property_id`
where
`record_user`.`user_id` = '1' and `record_user`.`role` = 'singer' or
`record_user`.`role` = 'songwriter'
The results for singer role are what is expected: All records where the user is the singer. The problem is the results for the songwriter: I am getting ALL songwriters and the query is not constrained by the user_id. For some reason I was expecting the songwriter role to also be constrained by the user_id - what is the correct way to write this using the eloquent syntax?
Hmm..I think you need to use an advanced where clause.
$results = Auth::user()
->records()
->where(function($query) {
$query->where('record_user.role', '=', 'singer')
->orWhere('record_user.role', '=', 'songwriter');
})
->get();
It is Laravel issue. In my case I solve it like this:
$results = Auth::user()
->records()
->wherePivot('role', 'singer')
->orWherePivot('role', 'songwriter')
->where('user_id', Auth::id())
->get();
Or use advance where clause
If your trying to get records I would do something similar to this:
User::find(Auth::user()->id)
->records()
->where(function($q){
$q->where('records.role', 'singer')
->orWhere('records.role', 'songwriter');
})->get();

Resources