ModelSearch Query error in Yii2 - php

I have two tables project and workload. I want show user in some project that added in Workload, and anothers member in this project (I called Team Member of that Project), too.
My idea is join 2 tables project and workload with user_id condition to take projects of user have user_id, then, from that will join with workload table again to take data from project of user have that user_id and user_id of team member will have that projects.
That my code in WorkloadSearch.php
public function searchWorkloadofUser($params) {
$user_id = Yii::$app->user->id;
$query = Workload::find()
->select(['workload.project_id', 'workload.commit_time', 'project.project_name', 'workload.from_date', 'workload.to_date', 'workload.workload_type', 'workload.comment'])
->join('INNER JOIN', 'project', 'workload.project_id=project.id')
->where('workload.user_id = '.$user_id)->orderBy('project.project_name ASC')->distinct();
$query->join('INNER JOIN','workload', 'project.id = workload.project_id')->distinct();
}
I don't understand why appeared error:
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'workload'
The SQL being executed was: SELECT COUNT(*) FROM (SELECT DISTINCT `workload`.`project_id`, `workload`.`commit_time`, `project`.`project_name`, `workload`.`from_date`, `workload`.`to_date`, `workload`.`workload_type`, `workload`.`comment` FROM `workload` INNER JOIN `project` ON workload.project_id=project.id INNER JOIN `workload` ON project.id = workload.project_id WHERE workload.user_id = 20) `c`

like the others said: You need an alias. Your error messages tells you:
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'workload'
This is beacause you joined your table worload to your workload table:
$query = Workload::find() //your `workload` table
->select([
....
])
->join('INNER JOIN', 'project p'], 'workload.project_id=p.id')
->where('workload.user_id = '.$user_id)
->orderBy('p.project_name ASC')
->distinct();
$query->join('INNER JOIN','workload', 'project.id = workload.project_id') //join the `workload` table to the `workload` table
->distinct();
When you want to join a table to itself, you have to define an alias at least for the joining table.
I would recommend you to quote the tablenames and columns whis is described in the Yii2 guide here and do not concat strings but bind params like it's described here and here. This code should work for you (not tested):
$query = Workload::find() //your `workload` table
->select([
'{{workload}}.[[project_id]]', //quoting tablenames and columns
'{{%workload}}.[[commit_time]]', //add '%' when you're using table prefix
...
])
->join('INNER JOIN', 'project p'], 'workload.project_id=p.id')
->where('workload.user_id' = :user_id, [':user_id' => $user_id]) //You should bind params when use string format
//or use hash format
//->where(['workload.user_id' => $user_id])
...
$query->join('INNER JOIN','workload w2', 'project.id = w2.project_id') //Use the alias `w2` to join the `workload` table to the `workload` table
->distinct();

You need to give the user table an alias the second time you join to it
e.g.
SELECT workload.project_id, workload.commit_time, p.project_name, ...
FROM workload
LEFT JOIN project p ON p.id = workload.project_id
WHERE workload.user_id = '1'
Your solution should be (untested):
public function searchWorkloadofUser($params)
{
$user_id = Yii::$app->user->id;
$query = Workload::find()
->select(['workload.project_id', 'workload.commit_time', 'p.project_name', 'workload.from_date', 'workload.to_date', 'workload.workload_type', 'workload.comment'])
->join('INNER JOIN', 'project p'], 'workload.project_id=p.id')
->where('workload.user_id = '.$user_id)->orderBy('p.project_name ASC')->distinct();
...

Related

How Get Count in Join Query in Laravel

I want to convert the following SQL to Laravel.
SELECT COUNT('uc.*') AS count_down, bs.brand_name
FROM `user_activities` AS uc
JOIN brands AS bs ON uc.brand_id = bs.id
GROUP BY uc.brand_id
ORDER BY count_down DESC
LIMIT 5
But when doing this:
$top_donwload_list = DB::table('user_activities')
->leftJoin('brands', 'brands.id', '=', 'user_activities.brand_id')
->selectRaw('brands.*, brands.brand_name, brands.id, count(user_activities.action_type) as user_activitiesCount')
->groupBy('user_activities.brand_id')
->get();
I get this error:
SQLSTATE[42000]: Syntax error or access violation: 1055 'colorworld.brands.id' isn't in GROUP BY (SQL: select brands.*, brands.brand_name, brands.id, count(user_activities.action_type) as user_activitiesCount from user_activities left join brands on brands.id = user_activities.brand_id group by user_activities.brand_id)
I tried to set 'strict' => true, in database.php but I get the same error in Laravel 5.7.
Update:- database table
If I understood your question correctly, you are trying to find the count of user activities grouped by a brand's name. Also you want the top 5 records ordered by the ones with the most user activities.
So, the following should work:
$top_donwload_list = DB::table('user_activities')
->selectRaw("brands.brand_name, COUNT('user_activities.*') as user_activitiesCount")
->join('brands', 'brands.id', '=', 'user_activities.brand_id')
->groupBy('brands.brand_name')
->orderBy('user_activitiesCount', 'desc')
->take(5)
->get();
You can use Laravel Eloquent. I Assume that the relationship between brand and user_activities is one to many and Here, the "Brand" is the model of the brand entity.
$count = Brand::leftJoin
('user_activities', function($join_brands){
$join_brands-> on
('brands.id', '=','user_activity.brand_id');
)->orderBy('user_activities.count_down','desc ')
->groupBy('user_activities.brand_id')->count();

Adding raw query to eloquent relationship

I am developing an application in Laravel 5.6 I'm having a simple table with following columns:
company_id project_id company_role_id company_specialisation_id
And this represents the model AssociateCompanies, which has relation of company, project, role, specialisation now I am having some query to get the attribute:
$companies = AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->groupBy('company_id', 'company_specialisation_id')->with('company', 'role', 'specialisation');
I want to collect all unique fields with their counts from two columns company_id and specialisation_id, but groupBy is not giving me proper the results so I am unbale to proceed further:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'conxn.project_associate_company.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select * from project_associate_company where exists (select , (select count() from project_associate_company where companies.id = project_associate_company.company_id and project_associate_company.deleted_at is null) as associated_projects_count from companies where project_associate_company.company_id = companies.id and exists (select * from projects inner join project_owner_relation on projects.id = project_owner_relation.project_id where companies.id = project_owner_relation.company_id and slug = lodha-patel-estate-tower-a-b-mumbai and projects.deleted_at is null) and companies.deleted_at is null) and project_associate_company.deleted_at is null group by company_id, company_specialisation_id)"
So I tried running raw queries like this:
$companies = AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->selectRaw(DB::raw('COUNT(*) AS count GROUP BY company_id , company_specialisation_id'))
->with('company', 'companyRole', 'specialisation')->get();
SQLSTATE[42000]: Syntax error or access violation: 1064 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 'GROUP BY company_id , company_specialisation_id from project_associate_company' at line 1 (SQL: select COUNT(*) AS count GROUP BY company_id , company_specialisation_id from project_associate_company where exists (select , (select count() from project_associate_company where companies.id = project_associate_company.company_id and project_associate_company.deleted_at is null) as associated_projects_count from companies where project_associate_company.company_id = companies.id and exists (select * from projects inner join project_owner_relation on projects.id = project_owner_relation.project_id where companies.id = project_owner_relation.company_id and slug = lodha-patel-estate-tower-a-b-mumbai and projects.deleted_at is null) and companies.deleted_at is null) and project_associate_company.deleted_at is null)"
Suggest me better way to get this. Thanks.
Initially I want to notice you can not "group by" inside the "select" statement.
So you can not aggregate the non-aggregated columns. This means is grouped fields can be has got multiple "role" so you can not "load" the "roles". The query should be like the one of the follows:
AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->select('company_id', 'company_specialisation_id', \DB::raw('COUNT(*) as cnt'))
->groupBy('company_id', 'company_specialisation_id')
->with('company', 'specialisation');
Or :
AssociateCompany::whereHas('company', function ($q) use ($request) {
$q->whereHas('projectOwners', function ($q) use($request) {
$q->where('slug', $request->slug);
});
})->select('company_id', 'company_specialisation_id', 'company_role_id', \DB::raw('COUNT(*) as cnt'))
->groupBy('company_id', 'company_specialisation_id', 'company_role_id')
->with('company', 'specialisation', 'role');
My suggestions are like this but I think you can solve it with raw MySQL queries rather than use to Eloquent.

Join three tables and orderBy in laravel getting an error

I'm trying to use join() in laravel5.1 but I'm getting this error:
QueryException in Connection.php line 666: SQLSTATE[23000]: Integrity
constraint violation: 1052 Column 'id' in where clause is ambiguous
(SQL: select * from quizzes inner join question_numbers on
question_numbers.quiz_id = quizzes.id and
question_numbers.question_id = multiple_choice.id inner join
multiple_choice on multiple_choice.id =
question_numbers.question_id where id = 1)
I have three tables here and I want to join these three tables. What I want first is to get a quiz where id = to a specific id then join the table question_numbers where question_numbers.quiz_id is = to the quiz.id then join the table multiple_choice where multiple_choice.id is = question_numbers.question_id and where question_numbers.question_type = multiple_choice.
What I have:
$quiz = DB::table('quizzes')->where('id', $id)
->join('question_numbers', function($join){
$join->on('question_numbers.quiz_id', '=', 'quizzes.id')
->on('question_numbers.question_id', '=', 'multiple_choice.id');
})
->join('multiple_choice', 'multiple_choice.id', '=', 'question_numbers.question_id')
->get();
dd($quiz);
First, you need to set a table aliaslike this quizzes as t for your table that belongs the where condition's id (I assume you meant quizzes table id column here) and then if you refer it inside where like where('t.id', $id), it will not complain about the ambiguous integrity because other table also have id column that's why it is showing you the below Query exception,
Column 'id' in where clause is ambiguous
Try like this,
$quiz = DB::table('quizzes as t')->where('t.id', $id)
->join('question_numbers', function($join){
$join->on('question_numbers.quiz_id', '=', 't.id');
})
->join('multiple_choice', 'multiple_choice.id', '=', 'question_numbers.question_id')
->get();
dd($quiz);

laravel complex query building with join and groupBy

I am new to laravel and have the following query in core PHP that needs to be laravel query.
$query="select distinct(c.c_id), 1 'companyToken',c.companyname,u.email,creation_date,CONCAT(eu.firstname,' ',eu.lastname) 'Name' , group_concat(pk.package_name) 'Package Name/Service' , c.notes 'Notes' , c.demo_status 'Demo Status' from ee_company c
left join et_company_payment_methods cpm on cpm.c_id=c.c_id
left join et_packages pk on cpm.package_id = pk.id
inner join (SELECT *
FROM `ee_users`
WHERE c_id IS NOT NULL
GROUP BY c_id) u on u.c_id=c.c_id
left join ee_users eu on eu.id=c.referred_by_user_id
group by c.c_id";
i am just getting started with laravel so finding it difficult to convert such a complex query.
the existing system works fine with this query.
i tried building it with laravel.
$company = DB::table('ee_company')
->leftJoin('et_company_payment_methods', 'ee_company.c_id' , '=', 'et_company_payment_methods.c_id')
->leftJoin('et_packages', 'et_packages.id', '=', 'et_company_payment_methods.package_id')
->join('ee_users',function($join){
$join->on('ee_company.c_id', '=', 'ee_users.c_id')
->whereNotNull('ee_users.c_id')
->groupBy('ee_users.c_id');
})
->leftJoin('ee_users', 'ee_users.id', '=', 'ee_company.referred_by_user_id')
->groupBy('ee_company.c_id');
it gives me following error
Call to undefined method Illuminate\Database\Query\JoinClause::groupBy()
Try this one
$company = DB::table('ee_company')
->leftJoin('et_company_payment_methods', 'ee_company.c_id' , '=', 'et_company_payment_methods.c_id')
->leftJoin('et_packages', 'et_packages.id', '=','et_company_payment_methods.package_id')
->join(DB::raw('SELECT *
FROM `ee_users`
WHERE c_id IS NOT NULL
GROUP BY c_id'),function($join){
$join->on('u.c_id', '=', 'c.c_id');
})
->leftJoin('ee_users', 'ee_users.id', '=', 'ee_company.referred_by_user_id')
->groupBy('ee_company.c_id');

Error Number: 1066 Not unique table/alias: 'service' in codeigniter

Want to get all services in one to many relationship
My code is
$this->db->select('*');
$this->db->from('service');
$this->db->join('user', 'user.user_email = service.user_email', 'inner');
$this->db->join('service', 'service.user_email = user.user_email', 'inner');
$query = $this->db->get();
But it gives me an error
Error Number: 1066
Not unique table/alias: 'service'
SELECT * FROM (`service`) INNER JOIN `user` ON `user`.`user_email` = `service`.`user_email` INNER JOIN `service` ON `service`.`user_email` = `user`.`user_email`
Filename: C:\xampp\htdocs\service\system\database\DB_driver.php
If I do without
$this->db->from('service');
Then it gives syntax error
Error Number: 1064
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 'INNER JOIN `user` ON `user`.`user_email` = `service`.`user_email` INNER JOIN `se' at line 2
SELECT * INNER JOIN `user` ON `user`.`user_email` = `service`.`user_email` INNER JOIN `service` ON `service`.`user_email` = `user`.`user_email`
Filename: C:\xampp\htdocs\service\system\database\DB_driver.php
You are trying to join the service table to the user table and then trying to join the service table again.
This isn't something you should generally be trying to do, and when you do it this way, the rendered SQL statement contains two attempts to reference the service table. It's the second JOIN that causes the database pain and it throws the error that you're seeing.
In this instance, just use:
$this->db->select('*');
$this->db->from('service');
$this->db->join('user', 'user.user_email = service.user_email', 'inner');
$query = $this->db->get();
Since the
$this->db->join('service', 'service.user_email = user.user_email', 'inner');
is redundant here (you've already joined these tables on that field.

Categories