I have a joined table from siswa and kelas. in kelas table there is a column idSiswa, it comes from id from siswa table. the question is how I can get the id from kelas when its joined. when I try to fetch id it shows the id from siswa table, not from kelas table, I also already used right join and left join and still not get the answer
this is my kelas table
this is my siswa table
I using a query builder from laravel to run the query, and this is my query
$siswa = DB::table('siswas')
->join('kelas', 'kelas.idSiswa', '=', 'siswas.id')
->where([
['kelas.kelas', '2'],
['kelas.semester', 'ganjil'],
])
->select('kelas.*', 'siswas.*')
->get();
Your issue comes from a name conflict. When you join your two tables, there are 2 fields. To solve it, you should use SQL alias.
You can see an example on this topic
You could also consider using Eloquent which offers OOP advantages and automatically avoids this kind of issues.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Kelas extends Model
{
public function siswa()
{
return $this->belongsTo('App\Siswa', 'idSiswa', 'kelas');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Siswa extends Model
{
public function kelas()
{
return $this->hasMany('App\Kelas', 'idSiswa', 'kelas');
}
}
$siswa = App\Siswa::with('kelas')
->where([
['kelas', '2'],
['semester', 'ganjil'],
])
->get();
$firstSiswaKelasIds = $siswa->first()->kelas->map->id;
Related
The is the table structure,which basically has three tables,namely expenses,categories and sunbcategories
table expenses
(id,category_id,sub_category_id,date,description,amount)
table categories
(id,category_name)
table subcategories
(id,sub_category_name,category_id)
This is the SQL query that is needed
select expense.date, expense.description, expense.amount,
category.category_name, subcategory.sub_category_name
from expenses as expense,categories as category,subcategories as subcategory
where expense.category_id=category.id and
category.id=subcategory.category_id);
This is the function in Expense model with which I pass the category_id
The same query mentioned above is written in laravel, but I am not able to
fetch the data.
function fetchExpenseData($categoryId)
{
$expense = Expense::select("expenses.*","categories.category_name as
Categoryname","subcategories.Sub_category_name")
->join("categories","categories.id","=","expenses.category_id");
->join("subcategories",function($join)
{
$join>on("subcategories.category_id","=","expenses.category_id")
->on("suncategories.id","=","expenses.sub_category_id")
})->get();
return $expenses;
}
$expenses that are returned will be printed in blade.php.
Can I know what is the mistake
thanks in advance
Hye there ,
You need to add eloquent model for retrieving data fromenter code here three tables
Like
I have School Table , Student Table , Teacher Table
School is relating with both Student and Teacher then we will add relationship
In School Model
`
public function getStudent(){
return $this->hasMany('student_id' , App\Student);
}
public function getTeachers(){
return $this->hasMany('teacher_id' , App\Teacher);
}
In Student table
public function getSchool(){
return $this->hasOne('school_id' , App\School);
}
`
now call data from student
`
$students = Student::with('getSchool.getTeachers')->get()
This Demonstration for what I have get from your Question
I have two tables 'approval' and 'renewal', both having a common column 'applicant_id'.
When new application comes-in, it stores a data-record in table 'approval' alongwith the 'applicant_id' for whom the record has been added.
Now, when there is a renew applied for that same applicant, the row gets created in the table 'renewal' referencing the 'applicant_id'
Note: There can be a single record in the table 'approval' for a 'applicant_id' but there can be more than one record for the same 'applicant_id' in the table 'renewal'.
Now, my requirement is:
I need to fetch the records from both the table for all the applicants.
Conditions: If there is a data for the 'applicant_id' in both the table and 'renewal' table has multiple row for the same 'applicant_id', then I need to get the records from 'renewal' table only that too the latest one.
If there is no data in 'renewal' table but exists in 'approval' table for the 'applicant_id', then the fetch record should get the data present in 'approval' table.
Basically, if there is record for the applicant in 'renewal' table, get the latest one from there, if there is record present only in 'approval' table, then get that one but the preference should be to get from 'renewal' if exists.
I am trying to do this in laravel 5.2. So, is there anyone who can help me in this?
If you're using Eloquent, you'll have 2 models:
Renewal.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Renewal extends Model
{
protected $table = 'renewal';
public static function findMostRecentByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->orderBy('date_created', 'desc')
->first();
return $applicant;
}
}
Approval.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Approval extends Model
{
protected $table = 'approval';
public static function findByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->first();
return $applicant;
}
}
Then, in the code where you want to get the approval/renewal record, use the following code:
if (! $record = Renewal::findMostRecentByApplicantId($applicantId)) {
$record = Approval::findByApplicantId($applicantId);
}
//$record will now either contain a valid record (approval or renewal)
//or will be NULL if no record exists for the specified $applicantId
After few try, I got one way to do it using raw:
SELECT applicant_id, applicant_name, applicant_email, applicant_phone, renewed, updated_at
FROM (
SELECT renewal_informations.applicant_id, renewal_informations.applicant_name, renewal_informations.applicant_email, renewal_informations.applicant_phone, renewal_informations.renewed, renewal_informations.updated_at
FROM renewal_informations
UNION ALL
SELECT approval_informations.applicant_id, approval_informations.applicant_name, approval_informations.applicant_email, approval_informations.applicant_phone, approval_informations.renewed, approval_informations.updated_at
FROM approval_informations
) result
GROUP BY applicant_id
ORDER BY applicant_id ASC, updated_at DESC;
For every single Approval id, there can b multiple records for renewal table suggests you have One to Many relation. which you can define in the your Model like
Approval.php (App\Models\Approval)
public function renewal()
{
return $this->hasMany('App\Models\Renewal', 'applicant_id')
}
Having defined this relation. you can get the records from the table using applicant_id.
$renewal_request_records = Approval::find($applicant_id)->renewal();
This will get all records from renewal table against that applicant_id.
Finding the latest
$latest = Renewal::orderBy('desc', 'renewal_id')->first();
Further Readings Eloquent Relations
Hi i am developing job portal but facing a problem in pivot table filtering. i have a table like below
personal_details
id
name
sex
dob
nationality
visa_status
vacancies
id
name
description
created_at
updated_at
which have a many-to-many relation with pivot table.
Data here is inserted when a job-seeker apply for a vacancy
personal_detail_vacancy
id
personal_detail_id
vacancy_id
created_at
updated_at
PersonalDetail model
class PersonalDetail extends Model
{
public function vacancies()
{
return $this->belongsToMany('App\Vacancy')->withTimestamps();
}
}
Vacancy model
class Vacancy extends Model
{
public function personal_details()
{
return $this->belongsToMany('App\PersonalDetail');
}
what i want to do is select all personal detail who have applied for a job(in any vacancies) in a particular date
i tried
$personal_details = PersonalDetail::with(array('vacancies' => function($query){
$query->wherePivot('created_at', '2015-11-10 11:33:24');
}))->get();
but it is not filtering the date
ANY IDEA?
well solved this by using
$personal_details = PersonalDetail::whereHas('vacancies',function($query)
{
$query->where('created_at','2015-11-10 11:33:24');
})->get();
it was not working before. The problem was i had 'created_at' field in vacancies table also.
This query gives a pagination of all 'albums' with a picture and description for each. Now I am trying to get always the latest picture of each album.
I have tried to add a second orderBy('pics.created_at') , but that did not work. I think I need some kind of subquery but don't know how.
$query = AlbumPic::select(DB::raw('COUNT(pics.id) as picscount,
pics.url,
pics.user_id,
pics.created_at,
albums.id as album_id,
albums.title,
albums.text,
users.username'))
->join('albums','albums.id','=','album_pic.album_id')
->join('pics','pics.id','=','album_pic.pic_id')
->join('users','users.id','=','pics.user_id');
if(!is_null($user_id))
$query->where('album_pic.user_id',$user_id);
$albums = $query->groupBy('albums.id')
->orderBy('albums.created_at','desc')
->paginate(20);
edit
I made a mistake. I don't have created_at and updated_at in the album_pic table .
So my 'Album' - model/relations are now like this:
public function pics()
{
return $this->belongsToMany('Pic');
}
public function latestPic()
{
return $this->belongsToMany('Pic')->latest('pics.created_at');
}
And the query now looks like this:
$q = Album::with('pics')->with('latestPic.users');
if(!is_null($user_id))
$q->where('albums.user_id',$user_id);
$albums = $q->orderBy('albums.created_at','desc')
->paginate(20);
This works. Only thing I would like to improve is the way, the pictures per album are counted. Now I get all with with('pics') and then do a count($album->pics) in the view. If there is a way to not load everything, but only count the pictures, it would be nice.
You need to get the MAX(created_at) inside a subquery; see MySQL select MAX(datetime) not returning max value for example.
Really, though, if you're doing this in Laravel, it would be better to set these all up as relations and leverage the power of Eloquent. Then, you can define a relationship for pictures that uses ->latest() to return the most recent. See laravel eloquent query group by last id for an example (which uses one table, but the principle is the same for multiple tables).
Here's how you could set this up using Eloquent relations:
User model (User.php)
class User extends Eloquent {
public function albums()
{
return $this->hasMany('Album');
}
}
Album model (Album.php)
class Album extends Eloquent {
public function pics()
{
return $this->belongsToMany('Pic');
}
public function latestPic()
{
return $this->belongsToMany('Pic')->latest('album_pic.created_at');
}
}
Because you have a many-to-many relationship between albums and pics, in the latestPic() relation, you must specify the album_pic.created_at field for latest()—since we are actually interested in the order of entries in the pivot table, rather than in the pics table.
Finally, link this all together. For example, for a user with id of 1:
$albums = User::find(1)->albums()->with('pics')->with('latestPic')->paginate(20);
foreach($albums as $album) {
echo('<br>Album:');
var_dump($album->title);
echo('All pics:');
foreach($album->pics as $pic) {
var_dump($pic->url);
}
echo('Latest pic:');
$latestPic = $album->latestPic->first();
if ($latestPic) {
var_dump($latestPic->url);
}
}
Note that we are eager loading the pics and latestPic to reduce the number on calls to the database. Also note that accessing the $latestPic->url is wrapped in an if statement, otherwise albums that do not have any photos will throw an error since $album->latestPic would return null.
As #cedie correctly noted, Laravel doesn't handle pagination all that efficiently when using a groupBy statement, but that shouldn't be a problem in this case. The underlying queries do not use groupBy, so you should be save to use ->paginate(20).
Try using this in your select query:
max(pics.created_at) as created_at
instead of this:
pics.created_at
So your code should look like this:
AlbumPic::select(DB::raw('COUNT(pics.id) as picscount,
pics.url,
pics.user_id,
max(pics.created_at) as created_at,
albums.id as album_id,
albums.title,
albums.text,
users.username'))
Perhaps ypu can figure out how to adapt this for your purposes...
SELECT ap.*
, p.*
FROM album_pic ap
JOIN pics p
ON p.id = ap.pic_id
JOIN
( SELECT ap.*
, MAX(p.created_at) max_created_at
FROM album_pics ap
JOIN p.*
ON p.id = ap.pic_id
) x
ON x.album_id = ap.album_id
AND x.max_created_at = p.created_at;
I'm new in Cakephp 2.0, but I want to make a view of two tables with Inner Join.
I have the following tables tables:
hpsas with records: id, ciname, location, status
ldaps with records: id, ciname, status
The query I would do in MySQL is:
SELECT * FROM hpsas INNER JOIN ldaps ON hpsas.ciname = ldaps.ciname;
Which syntax do I have to use in whether the models, the controller or the view.
follow the activeRecord model i think you should define a relationship in the model to avoid running complex queries everytime you need records from this models. you will need to stick to cake's conventions tho and that means you will have 3 models(most possibly)
class cinema extends AppModel{
hasMany = array(hpsas,idaps);
}
class hpsas extends AppModel{
belongsTo = array(cinema)
}
class idap extends AppModel{
belongsTo = array(cinema)
}
with recursive set at above 2 or three one simple query to any one of the models will give you all the data you want(cake magic).
$options['joins'] = array(
array('table' => 'ldaps',
'type' => 'inner',
'conditions' => array(
'hpsas.ciname = ldaps.ciname',
)
)
);
$this->Hpsa->find('all', $options);
See Cake book section on associations for more details: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables