Php 识别mySQL表中作业代码的更改
我正在使用MySQL中的一个非常大的表,其中包含过去四年中收集的员工信息。我想知道是否有人的工作代码在这段时间内发生了变化,如果是这样,请将他们的数据放入一个数组中,以便在php中进行json编码 数据示例如下所示:Php 识别mySQL表中作业代码的更改,php,mysql,arrays,loops,Php,Mysql,Arrays,Loops,我正在使用MySQL中的一个非常大的表,其中包含过去四年中收集的员工信息。我想知道是否有人的工作代码在这段时间内发生了变化,如果是这样,请将他们的数据放入一个数组中,以便在php中进行json编码 数据示例如下所示: Year Emp ID Job Code 2015 1234 X908 2014 1234 X908 2013 1234 X908 **2015 5421 Y444** 20
Year Emp ID Job Code
2015 1234 X908
2014 1234 X908
2013 1234 X908
**2015 5421 Y444**
2014 5421 Z900
2013 5421 Z900
对于1234员工,2013-2015年期间没有任何工作变动;然而,我想抓住雇员5421,他们的工作代码在2014年至2015年间发生了变化
到目前为止,我已经用PHP编写了一个脚本,但没有得到很好的结果
$query = mysqli_query("SELECT year, emp_id, job_code from big_table ");
$rows = array();
while ($r = mysql_fetch_assoc($query)) {
if ($r['emp_id'] == $r['emp_id'] and $r['job_code'] != $r['job_code']) {
$rows[] = $r;
}
echo json_encode($rows);
提前感谢您的帮助 这个循环应该可以工作:
$rows = array();
$jobChanges = array();
while ($r = mysql_fetch_assoc($query)) {
if (!isset($rows[$r['emp_id']])){
$rows[$r['emp_id']] = $r;
} elseif ($rows[$r['emp_id']]['job_code'] != $r['job_code']) {
// Handle differing job_code...
if (!isset($jobChanges[$r['emp_id'])) {
$jobChanges[$r[emp_id]] = array();
}
// Keep track of all differing job codes per emp_id
// I am not going to go any further than that...
$jobChanges[$r[emp_id]][] = $r;
}
}
您可以在SQL查询中获得所需的数据,而无需将所有用户记录拉入PHP。这将比在PHP中处理数据更有效 您可以获取每个用户的作业代码计数:
SELECT emp_id, COUNT(DISTINCT job_code) AS diffjobs FROM big_table GROUP BY emp_id
然后,通过将作业代码包装到子查询中,可以有条件地获取具有1个以上不同作业代码的用户:
SELECT emp_id, diffjobs FROM
(SELECT emp_id, COUNT(DISTINCT job_code) AS diffjobs FROM big_table GROUP BY emp_id) d
WHERE diffjobs > 1
使用
GROUP BY
和HAVING
子句,您可以获得所需的员工,他们的工作在不同年份之间发生了变化,如下所示:
$query = mysqli_query($link, "SELECT emp_id from big_table GROUP BY emp_id HAVING COUNT(DISTINCT job_code) > 1");
$rows = array();
while ($r = mysqli_fetch_assoc($query)){
$rows[] = $r;
}
echo json_encode($rows);
注意:不要在代码中混合使用
mysqli
和mysql
数据库扩展。这可以通过mysql中的JOIN
查询来完成,这样您就只返回上一年更改的行-
SELECT
a.year, a.emp_id, a.job_code,
b.year prev_year, b.job_code prev_job_code
FROM big_table a
JOIN big_table b
ON a.emp_id = b.emp_id
AND b.year = a.year-1
WHERE a.job_code != b.job_code
看这把小提琴-
因此,您的代码可以简化为-
$query = mysqli_query("SELECT a.year, a.emp_id, a.job_code, b.year prev_year, b.job_code prev_job_code FROM big_table a JOIN big_table b ON a.emp_id = b.emp_id AND b.year = a.year-1 WHERE a.job_code != b.job_code ");
$rows = array();
while ($r = mysqli_fetch_assoc($query)) {
$rows[] = $r;
}
echo json_encode($rows);
注意-您有mysqli\u query()
,但是mysql\u fetch\u assoc()
,所以我更新为mysqli\u fetch\u assoc()
如果仍然希望在php中执行此操作,则需要将最后一行值保存到临时数组中,然后检查
job\u code
是否已更改
它看起来像这样-
$query = mysqli_query("SELECT year, emp_id, job_code from big_table ORDER BY emp_id, year");
$temp = array();
$rows = array();
while ($r = mysqli_fetch_assoc($query)) {
if(!isset($temp[$r['emp_id']]){
$temp[$r['emp_id']] = $r; // add this row to the temp array
}
else {
if ($r['job_code'] != $temp[$r['emp_id']]['job_code']) {
// add the previous values for comparison
$r['prev_year'] = $temp[$r['emp_id']]['year'];
$r['prev_job_code'] = $temp[$r['emp_id']]['job_code'];
// add this row
$rows[] = $r; // add this row
// replace the last temp array with this array
$temp[$r['emp_id']] = $r;
}
}
echo json_encode($rows);
注意-我更改了查询,添加了一个
ORDER by
->ORDER by emp\u id,year
您可能需要组织$rows数组,以便能够检查重复的员工,然后,如果发现重复的工作代码,检查工作代码,并从中为每个员工执行所需的操作。选择不同的emp\U id作为员工,对于每个员工选择不同的工作代码,如果工作代码大于1,则计算工作代码。如果(!isset($r['emp\U id']]){$rows[$r['emp\U id']=$r;}将为每个emp\u id
添加一行。OP只想在emp\u id
的job\u code
发生变化时添加一行。另外,$row
从哪里来?>$row[$r['emp\u id']]
谢谢Sebastian!我将尝试一下这种方法。哇,SQL工作得很好!谢谢,肖恩。不知道mysqli是如何潜入的,所以谢谢你的捕获。我的桌子上有超过20万条记录;当我运行这样的查询时,我必须将返回的行限制在50k左右,否则我的服务器会抛出500个错误。而且,即使在50k查询中,查询也需要10秒以上的时间。我确实索引了emp_id,但没有效果。关于如何在所有200+k记录上运行快速查询,有什么想法吗?谢谢啊,没关系,我发现了-没有在emp_id上正确设置索引谢谢Tristan,我会尝试这种方法。