Yii2 - viaTable join returns error - php

I am trying to write hasMany relationship, but I am getting this error:
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
'[[licences.id = userKeys.licence_id]] = `licences`.`0` LEFT JOIN `userKeys` `use' at line 1
The SQL being executed was:
SELECT COUNT(*) FROM `activityLogsUserActivity`
LEFT JOIN `users` ON `activityLogsUserActivity`.`user_id` = `users`.`id`
LEFT JOIN `licences` ON `activityLogsUserActivity`.[[licences.id = userKeys.licence_id]] = `licences`.`0`
LEFT JOIN `userKeys` `userKeys` ON `licences`.`user_id` = `userKeys`.`user_id`
The code:
public function getKeys()
{
return $this->hasMany(UserKeys::classname(), ['user_id' => 'user_id'])
->select('licences.licenceName, userKeys.*')
->from(['userKeys' => UserKeys::tableName()])
->viaTable(Licences::tableName(), ['licences.id = userKeys.licence_id']);
}
What am I doing wrong?

['licences.id = userKeys.licence_id']
should be a key-value pair, like
['id' => 'licence_id']
and it should not be necessary to declare the table name there, have a look at the docs
http://www.yiiframework.com/doc-2.0/yii-db-activequery.html#viaTable()-detail
The link between the junction table and the table associated with $primaryModel. The keys of the array represent the columns in the junction table, and the values represent the columns in the $primaryModel table.

Related

Why am is laravel throwing an SQLSTATE[42000]: Syntax error or access violation: 1064 Error

Am running a query builder on my laravel app using inner join
But Laravel keeps throwing errors, i tested the MySql Query
i wrote directly in my database using phpMyAdmin it works fine
SELECT
u.id, u.first_name, u.last_name, u.username, u.sponsor,u.deleted_at, i.id as investment_id, i.total_amount, i.created_at
FROM
users AS u
JOIN investments as i ON
i.id= ( SELECT i1.id FROM investments as i1 where u.id=i1.user_id and i1.status ='confirmed' ORDER BY i1.created_at LIMIT 1)
WHERE
u.sponsor = '901d08da-e6c4-476a-ae7b-9386990b8b9e' AND u.deleted_at is NULL
ORDER BY
created_at DESC
but when i write it using query builder it wont work.
$refered_users = DB::table('users')
->join('investments', function ($join) {
$join->on('users.id', '=', 'investments.user_id')
->where('investment.status', '=', 'confirmed')
->orderBy('investment.created_at','desc')->first();
})
->select('users.id,users.first_name,users.last_name,users.username,users.sponsor,investment.id AS investment_id,investment.total_amount,investment.created_at')
->where('users.sponsor','=',Auth::User()->id)
->orderBy('investment.created_at','desc')
->paginate(10);
i tried a RAW DB::select() and it works but i want to use the query builder so i can paginate the results.
this is how my table is arranged:
users
id, first_name, last_name, username, sponsor(id of another user), created_at, deleted_at
investments
id, total_amount , user_id(id of a user), status, created_at, deleted_at
Am not much Good with SQL Queries so if am writing it all wrong please don't scold just, try to explain a lil bit more so i can understand
this is the error coming out:
Illuminate\Database\QueryException
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 'on users.id = investments.user_id and
investment.status = ? order by' at line 1 (SQL: select * on
users.id = investments.user_id and investment.status =
confirmed order by investment.created_at desc limit 1)
output of the dd
select first_name,last_name,username,deleted_at,total_amount,
investment_created_at,user_id from `users`
inner join (select user_id,total_amount,status,created_at AS investment_created_at from `investments`
where `status` = ? and `investments`.`deleted_at` is null) as `confirmed_investments`
on `users`.`id` = `confirmed_investments`.`user_id`
where `sponsor` = ? order by `investment_created_at` desc ◀`
`array:2 [▼ 0 => "confirmed" 1 => "901d08da-e6c4-476a-ae7b-9386990b8b9e" ]`
am using:
PHP version: 7.3.1
MySql Version: 8.0.18
You can get query of your code and compare it to your desired query like this:
$refered_users = DB::table('users')
->join('investments', function ($join) {
$join->on('users.id', '=', 'investments.user_id')
->where('investment.status', '=', 'confirmed')
->orderBy('investment.created_at','desc')->first();
})
->select('users.id,users.first_name,users.last_name,users.username,users.sponsor,investment.id AS investment_id,investment.total_amount,investment.created_at')
->where('users.sponsor','=',Auth::User()->id)
->orderBy('investment.created_at','desc')
->toSql();
Your join query is getting data for id by running another query. I think you need to use sub query. If you are using laravel > 6 it is on documentation.

Laravel merge multiple rows as multiple columns

So I have four tables:
experiments (tables) - id
feature_classes (columns) - id, experiment_id, title
entities (rows) - id, experiment_id
features (cells) - id, entity_id, feature_class_id, value
I need to construct a table from these four tables.
I tried this:
$experiment_id = $request->input('experiment_id');
$feature_classes = FeatureClass::where('experiment_id', $experiment_id)->select('title', 'id')->get();
$select = [
'entities.id',
'entities.prediction',
'entities.result'
];
foreach ($feature_classes as $f) {
$select[] = $f->id . ".value AS " .$f->id;
}
$entities = DB::table('entities')
->where('experiment_id', $experiment_id);
foreach ($feature_classes as $f) {
$entities = $entities->leftJoin('features AS ' . $f->id, function ($join) use ($f){
$join->on($f->id . '.entity_id', '=', 'entities.id')
->where($f->id . '.feature_class_id', $f->id);
});
}
return $entities
->select($select)
->get();
But my efforts are rewarded with this error message SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '1 ? left joinfeaturesas2on2.entity_id=entities.idand2.fe' at line 1 (SQL: select entities.id, entities.prediction, entities.result, 1.value as 1, 2.value as 2 from entities left join features as 1 on 1.entity_id = entities.id and 1.feature_class_id 1 left join features as 2 on 2.entity_id = entities.id and 2.feature_class_id 2 where experiment_id = 1) `
I'd argue that you shouldn't have to. You should approach this by adding the many to many relations in the model only, then using eloquent to do all the rest. For example, in the features model:
public function Classes(){
return $this->belongsToMany('App\Classes', 'feature_classes', 'feature_class_id', 'id');
}
Then something similar that defines the relationship between classes and entities linking by experiment_id. Then you should be able to access the data you need by using the native eloquent features like
$entities = Features::where('experiment_id', $experiment_id)->Classes->Entities;
return $entities
More information here:
https://laravel.com/docs/5.3/eloquent-relationships#many-to-many

Getting unknown property Yii 2 Joinwith

Hello I have been getting Getting unknown property: app\models\ActiveCurriculum::period the period column is located at the schead table
I have used this code to join the tables.
ActiveCurriculum::find()
->select('scstock.*')
->joinWith('schead')
->where(['schead.TrNo' => $TrNo])
->one();
Can you help me?
EDIT 1 (fixed)
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'WHERE schead.TrNo='29005'' at line 1
The SQL being executed was: SELECT scstock.* FROM scstock LEFT JOIN schead WHERE schead.TrNo='29005'
Edit 2: I managed to fix it but I am getting a new error again
"A join clause must be specified as an array of join type, join table, and optionally join condition."
ActiveCurriculum::find()
->select(`scstock.*`)
->leftJoin(`schead`)
->where([`schead.TrNo` => $TrNo])
->one();
ActiveCurriculum::find()->select('scstock.*')
->joinWith('schead')
->where(['schead.TrNo' => $TrNo])
->one();
// here joinWith('schead') means `schead` is name of the class
ActiveCurriculum::find()->select('scstock.*')
->joinLeft('schead','schead.scheadid=scstock.scheadid') // scheadid is the common field between two fields
->where(['schead.TrNo' => $TrNo])
->one();

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.

Inner join with codeigniter

i have a query as follows and it gives me a error
my query in model is
$query = $this->db->select('SELECT AV.Ad_ID, AV.Title, AV.Price, LT1.Listing')
->from('ad_vehicle')
->join('ref_listing_type', 'ad_vehicle.Listing_Type_ID = ref_listing_type.Listing_ID', 'inner')
->where('ad_vehicle.Created_By', 1)
->get();
var_dump($query);
return $query->result_array();
and my error is
A Database Error Occurred
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 '.Ad_ID, AV.Title, AV.Price, LT1.Listing FROM
(ad_vehicle) INNER JO' at line 1
SELECT `SELECT` AV.Ad_ID, `AV`.`Title`, `AV`.`Price`, `LT1`.`Listing`
FROM (`ad_vehicle`)
INNER JOIN `ref_listing_type` ON `ad_vehicle`.`Listing_Type_ID` = `ref_listing_type`.`Listing_ID`
WHERE `ad_vehicle`.`Created_By` = 1
Filename: C:\wamp\www\DoolalyJobsBackup\system\database\DB_driver.php
Line Number: 330
Change your select() to
$query = $this->db->select('AV.Ad_ID, AV.Title, AV.Price, LT1.Listing')
Using active record's select() will automatically adds a SELECT keyword you don't need to add again in your query,Also in your query you have used short aliases for the tables but you haven't assign them
$this->db->select('AV.Ad_ID, AV.Title, AV.Price, LT1.Listing')
->from('ad_vehicle AV')
->join('ref_listing_type LT1', 'AV.Listing_Type_ID = LT1.Listing_ID', 'inner')
->where('AV.Created_By', 1)
->get();

Categories