问题
I had searching application, finding personal information which had been filtered by some criteria (category, years of experience etc)
I had problem with the last filter, 'tempoh perkhidmatan by negeri'. I need to calculate the number of working experience by state(negeri). For example, when searching for people of 5 years in the state(negeri) 'x', the sql will sum years of experience of each person in the state selected.
This is the full code of SQL searching by criteria:
$query = DB::table('itemregistrations')
->join('sections', 'itemregistrations.SectionID', '=', 'sections.SectionID')
->join('categories', 'itemregistrations.CategoryID', '=', 'categories.CategoryID')
->join('operasi', 'itemregistrations.OperasiID', '=', 'operasi.OperasiID')
->join('negeri', 'itemregistrations.NegeriID', '=', 'negeri.NegeriID')
->join('gred', 'itemregistrations.GredID', '=', 'gred.GredID')
->where('itemregistrations.statusProID', '=', 1)
->select('itemregistrations.name','sections.sectionname', 'categories.categoryname', 'operasi.operasiname', 'itemregistrations.Nobadan', 'itemregistrations.lahir_yy', 'itemregistrations.pdrm_yy', 'gred.namagred', 'itemregistrations.itemRegistrationID', '');
if($request->input('negeri_lahir') != ''){
$query->where('itemregistrations.NegeriID', $request->input('negeri_lahir'));
}
if($request->input('kategori') != '') {
$query->where('itemregistrations.CategoryID', $request->input('kategori'));
}
if($request->input('pangkat') != '') {
$query->where('itemregistrations.OperasiID', $request->input('pangkat'));
}
if(request('umur')) {
$query->whereRaw('YEAR(CURDATE()) - lahir_yy >= ?', [request('umur')]);
}
if($request->input('gred') != '') {
$query->where('itemregistrations.GredID', $request->input('gred'));
}
if(request('tempoh')) {
$query->whereRaw('YEAR(CURDATE()) - pdrm_yy >= ?', [request('tempoh')]);
}
if($request->input('negeri_perkhidmatan') != '') {
$query->join('itemregistrationpangkat', 'itemregistrationpangkat.itemRegistrationID', '=', 'itemregistrations.itemRegistrationID')
->where('itemregistrationpangkat.NegeriID', $request->input('negeri_perkhidmatan'));
}
if(request('tempoh_negeri')) {
$query->select(DB::raw('m.itemRegistrationID, sum(m.duration)'))
->from(DB::raw('(SELECT itemRegistrationID, NegeriID, yeartamatkhidmat - yearmulakhidmat as duration FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations ON itemregistrations.itemRegistrationID=m.itemRegistrationID'))
->distinct()
->groupBy('m.itemRegistrationID');
}
$newitem = $query->get();
return response::json($newitem);
The code involve to be solve is this(the last filter):
if(request('tempoh_negeri')) {
$query->select(DB::raw('m.itemRegistrationID, m.NegeriID, sum(distinct m.duration)'))
->from(DB::raw('(SELECT itemRegistrationID, NegeriID, yeartamatkhidmat - yearmulakhidmat as duration FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations ON itemregistrations.itemRegistrationID=m.itemRegistrationID'))
->groupBy('m.itemRegistrationID', 'm.NegeriID');
}
The problem is I need to get name column, sectionID column, CategoryID, OperasiID, NegeriID, GredID, from itemregistrations table from the $query statement. How to combine the last query filter in 'tempoh_negeri' with the previous one?
回答1:
I didn't know about Laravel in particular, so I had much trouble trying to understand how your query was built, but this syntax seems to enable people to write a request by adding chunks, but not necessarily in the right order. So here's what I believe your query is supposed to do, for SQL speakers:
SELECT itemregistrations .name,
sections .sectionname,
categories .categoryname,
operasi .operasiname,
itemregistrations .Nobadan,
itemregistrations .lahir_yy,
itemregistrations .pdrm_yy,
gred .namagred,
itemregistrations .itemRegistrationID
-- if($tempoh_negeri) (request)
,m .itemRegistrationID,
sum(m.duration)
FROM itemregistrations
-- if($tempoh_negeri) (request)
,(SELECT DISTINCT itemRegistrationID,
NegeriID,
yeartamatkhidmat - yearmulakhidmat as duration
FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations
ON itemregistrations.itemRegistrationID = m.itemRegistrationID
JOIN sections
ON itemregistrations.SectionID = sections.SectionID
JOIN categories
ON itemregistrations.CategoryID = categories.CategoryID
JOIN operasi
ON itemregistrations.OperasiID = operasi.OperasiID
JOIN negeri
ON itemregistrations.NegeriID = negeri.NegeriID
JOIN gred
ON itemregistrations.GredID = gred.GredID
-- if($negeri_perkhidmatan)
JOIN itemregistrationpangkat
ON itemregistrationpangkat.itemRegistrationID = itemregistrations.itemRegistrationID
WHERE itemregistrations.statusProID = 1
-- if($negeri_lahir) (WHERE)
AND itemregistrations.NegeriID = $negeri_lahir
-- if($kategori) (WHERE)
AND itemregistrations.CategoryID = $kategori
-- if($pangkat) (WHERE)
AND itemregistrations.OperasiID = $pangkat
-- if(umur) (WHERERAW) (request)
AND YEAR(CURDATE()) - lahir_yy >= umur
-- if($gred) (WHERE)
AND itemregistrations.GredID = $gred
-- if($tempoh) (WHERERAW) (request)
AND YEAR(CURDATE()) - pdrm_yy >= tempoh
-- if($negeri_perkhidmatan)
AND itemregistrationpangkat.NegeriID = $negeri_perkhidmatan
-- if($tempoh_negeri) (request)
GROUP BY m.itemRegistrationID
If it's so, you cannot do what you want following that way (including main columns into the subquery) because your subquery will be evaluated BEFORE the main one is.
Instead, you need to write a proper filter at main query level, that is : among the others "JOIN…ON" clauses already in place. Which would give:
LEFT JOIN itemregistrationpangkat
ON itemregistrationpangkat.itemRegistrationID = itemregistrations.itemRegistrationID
… then specify the substraction directly in your sum()
function
sum(yeartamatkhidmat - yearmulakhidma)
As regards Lavarel, this probably would give something like:
if(request('tempoh_negeri')) {
$query->leftjoin('itemregistrationpangkat','itemRegistrationID','=','itemregistrations.itemRegistrationID');
$query->select(DB:raw('sum(yeartamatkhidmat - yearmulakhidmat'));
}
来源:https://stackoverflow.com/questions/55860103/how-to-get-other-column-value-in-different-table-into-the-query