如何将子查询与其他 table 集成并抓取名称列?
How to integrate subquery with other table and grab name column?
我有搜索应用程序,从 itemregistrationpangkat table:
中找到已按某些标准(类别、经验年限等)过滤的个人信息
itemregistrationpangkatID|itemregistrationID|NegeriID|yeartamatkhidmat|yearmulakhidmat
--------------------------------------------------------------------------
1 | 2 | Kedah | 2001 | 2002
2 | 2 | Kedah | 2003 | 2007
3 | 3 | Melaka | 2008 | 2012
4 | 3 | Melaka | 2013 | 2018
5 | 4 | KL | 2000 | 2001
itemregistrationID | name | SectionID | CategoryID
-----------------------------------------------------------
1 | Eric | 1 | 2
2 | Tom | 2 | 4
3 | Anne | 2 | 4
4 | Marie | 3 | 2
5 | Bill | 1 | 3
我对最后一个过滤器 'tempoh perkhidmatan by negeri' 有疑问。我需要按州(negeri)计算工作经验的数量。例如,当搜索在州 (negeri) 'x' 工作 5 年的人时,sql 将汇总每个人在所选州的工作年限。
这是 SQL 按条件搜索的完整代码:
$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);
需要解决的代码是这个(最后一个filter):
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');
}
问题是重复的行。
上面的控制台日志显示:
0:
itemRegistrationID: 791
sum(m.duration): 6
据推测:
0:
itemRegistrationID: 791
sum(m.duration): 3
distinct() 不适用于 groupby,如果我删除 groupby,它可以删除重复的行。
我认为它显示重复的原因是因为RIGHT JOIN
。我自己测试了相同的条件,下面是我的测试示例:
--Lets say my itemregistrations table look like this:
+----------------------+-------------+------------+
| itemRegistrationID | firstname | lastname |
+----------------------+-------------+------------+
| 1 | A | B |
| 2 | C | D |
| 3 | E | F |
| 1 | A | A |
+----------------------+-------------+------------+
-- notice that there are repeated value of = 1 in itemregistrationID
-- And my itemregistrationpangkat table look like this:
+----------------------+------------+--------------------+-------------------+
| itemRegistrationID | NegeriID | yeartamatkhidmat | yearmulakhidmat |
+----------------------+------------+--------------------+-------------------+
| 1 | J | 2019-04-26 | 2009-12-01 |
| 2 | S | 2018-12-31 | 1999-08-19 |
| 3 | P | 2017-12-31 | 2001-03-02 |
+----------------------+------------+--------------------+-------------------+
我提取了上面的 MySQL 查询,变成了这个:
SELECT m.itemRegistrationID, SUM(m.duration)
FROM
(SELECT itemRegistrationID, NegeriID,
YEAR(yeartamatkhidmat) - YEAR(yearmulakhidmat) AS duration
FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations
ON itemregistrations.itemRegistrationID=m.itemRegistrationID
GROUP BY m.itemRegistrationID;
-- with the query above, my results are as following:
+----------------------+-------------------+
| itemRegistrationID | sum(m.duration) |
+----------------------+-------------------+
| 1 | 20 |
| 2 | 19 |
| 3 | 16 |
+----------------------+-------------------+
为了查看导致 id=1 具有重复值的原因,我执行如下查询:
SELECT * FROM
(SELECT itemRegistrationID, NegeriID,
YEAR(yeartamatkhidmat) - YEAR(yearmulakhidmat) AS duration
FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations ON
itemregistrations.itemRegistrationID=m.itemRegistrationID;
-- and it shows the following result:
+----------------------+------------+------------+----------------------+-------------+------------+
| itemRegistrationID | NegeriID | duration | itemRegistrationID | firstname | lastname |
+----------------------+------------+------------+----------------------+-------------+------------+
| 1 | J | 10 | 1 | A | B |
| 1 | J | 10 | 1 | A | A |
| 2 | S | 19 | 2 | C | D |
| 3 | P | 16 | 3 | E | F |
+----------------------+------------+------------+----------------------+-------------+------------+
当然,通过在您的 SELECT
中添加 SUM(DISTINCT m.duration)
,它将删除任何 m.duration
重复项。这是我担心的地方。我不认为 m.duration
应该是决定重复的因素,因为你有 itemregistrationID
和 NegeriID
所以它们的组合应该是独一无二的(或者至少来自其他领域的一些组合而不是那两个将是独一无二的)。我的进一步测试表明,如果 itemregistrationpangkat
table 有两个 itemRegistrationID
具有不同的 NegeriID
等,SUM(DISTINCT m.duration)
将不起作用。如果我找到更好的方法,让我尝试一下并更新我的答案。
更新:
我在这里创建了一个 fiddle:DB Fiddle
我有搜索应用程序,从 itemregistrationpangkat table:
中找到已按某些标准(类别、经验年限等)过滤的个人信息 itemregistrationpangkatID|itemregistrationID|NegeriID|yeartamatkhidmat|yearmulakhidmat
--------------------------------------------------------------------------
1 | 2 | Kedah | 2001 | 2002
2 | 2 | Kedah | 2003 | 2007
3 | 3 | Melaka | 2008 | 2012
4 | 3 | Melaka | 2013 | 2018
5 | 4 | KL | 2000 | 2001
itemregistrationID | name | SectionID | CategoryID
-----------------------------------------------------------
1 | Eric | 1 | 2
2 | Tom | 2 | 4
3 | Anne | 2 | 4
4 | Marie | 3 | 2
5 | Bill | 1 | 3
我对最后一个过滤器 'tempoh perkhidmatan by negeri' 有疑问。我需要按州(negeri)计算工作经验的数量。例如,当搜索在州 (negeri) 'x' 工作 5 年的人时,sql 将汇总每个人在所选州的工作年限。
这是 SQL 按条件搜索的完整代码:
$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);
需要解决的代码是这个(最后一个filter):
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');
}
问题是重复的行。 上面的控制台日志显示:
0:
itemRegistrationID: 791
sum(m.duration): 6
据推测:
0:
itemRegistrationID: 791
sum(m.duration): 3
distinct() 不适用于 groupby,如果我删除 groupby,它可以删除重复的行。
我认为它显示重复的原因是因为RIGHT JOIN
。我自己测试了相同的条件,下面是我的测试示例:
--Lets say my itemregistrations table look like this:
+----------------------+-------------+------------+
| itemRegistrationID | firstname | lastname |
+----------------------+-------------+------------+
| 1 | A | B |
| 2 | C | D |
| 3 | E | F |
| 1 | A | A |
+----------------------+-------------+------------+
-- notice that there are repeated value of = 1 in itemregistrationID
-- And my itemregistrationpangkat table look like this:
+----------------------+------------+--------------------+-------------------+
| itemRegistrationID | NegeriID | yeartamatkhidmat | yearmulakhidmat |
+----------------------+------------+--------------------+-------------------+
| 1 | J | 2019-04-26 | 2009-12-01 |
| 2 | S | 2018-12-31 | 1999-08-19 |
| 3 | P | 2017-12-31 | 2001-03-02 |
+----------------------+------------+--------------------+-------------------+
我提取了上面的 MySQL 查询,变成了这个:
SELECT m.itemRegistrationID, SUM(m.duration)
FROM
(SELECT itemRegistrationID, NegeriID,
YEAR(yeartamatkhidmat) - YEAR(yearmulakhidmat) AS duration
FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations
ON itemregistrations.itemRegistrationID=m.itemRegistrationID
GROUP BY m.itemRegistrationID;
-- with the query above, my results are as following:
+----------------------+-------------------+
| itemRegistrationID | sum(m.duration) |
+----------------------+-------------------+
| 1 | 20 |
| 2 | 19 |
| 3 | 16 |
+----------------------+-------------------+
为了查看导致 id=1 具有重复值的原因,我执行如下查询:
SELECT * FROM
(SELECT itemRegistrationID, NegeriID,
YEAR(yeartamatkhidmat) - YEAR(yearmulakhidmat) AS duration
FROM itemregistrationpangkat) AS m
RIGHT JOIN itemregistrations ON
itemregistrations.itemRegistrationID=m.itemRegistrationID;
-- and it shows the following result:
+----------------------+------------+------------+----------------------+-------------+------------+
| itemRegistrationID | NegeriID | duration | itemRegistrationID | firstname | lastname |
+----------------------+------------+------------+----------------------+-------------+------------+
| 1 | J | 10 | 1 | A | B |
| 1 | J | 10 | 1 | A | A |
| 2 | S | 19 | 2 | C | D |
| 3 | P | 16 | 3 | E | F |
+----------------------+------------+------------+----------------------+-------------+------------+
当然,通过在您的 SELECT
中添加 SUM(DISTINCT m.duration)
,它将删除任何 m.duration
重复项。这是我担心的地方。我不认为 m.duration
应该是决定重复的因素,因为你有 itemregistrationID
和 NegeriID
所以它们的组合应该是独一无二的(或者至少来自其他领域的一些组合而不是那两个将是独一无二的)。我的进一步测试表明,如果 itemregistrationpangkat
table 有两个 itemRegistrationID
具有不同的 NegeriID
等,SUM(DISTINCT m.duration)
将不起作用。如果我找到更好的方法,让我尝试一下并更新我的答案。
更新: 我在这里创建了一个 fiddle:DB Fiddle