按列值对多行结果集数据进行分组
Group multiples rows of result set data by a column value
我想将分配给特定员工的逾期任务作为电子邮件摘要发送。多个待办事项可能分配给同一个员工。因此可以将多个待办事项分配给同一名员工并且已过期。这就是问题开始的地方...
所以我所做的是从数据库中抓取所有逾期任务,然后抓取分配给任务的员工。我创建了一个由 todoID
、employeeID
和 employeeEmail
组成的数组。现在,是否有更好的方法来执行此操作,如果没有,我如何按电子邮件地址对行进行分组?
最终结果应该是一个数组,显示分配给一名员工的每个逾期待办事项。
// Get all Todos that are not archived
$sql = "SELECT * FROM todo WHERE archiv = 0";
$abfrage = $db->prepare($sql);
$abfrage->execute();
$overdue_array = array();
// Now we get everything that's overdue from the Database
while ($row = $abfrage->fetch()) {
if ($row["status"] !== 3) {
if ($row["archiv"] !== 1) {
if ($row["durchfuehrung"]) {
if (strtotime($row["durchfuehrung"]) < strtotime(date("Y-m-d"))) {
// Here we now get the email from the assiged employee to the todo
$sql2 = "SELECT email FROM mitarbeiter WHERE mitarbeiterID = :mitarbeiterFID";
$abfrage2 = $db->prepare($sql2);
$abfrage2->bindParam("mitarbeiterFID", $row["mitarbeiterFID"]);
$abfrage2->execute();
while ($row2 = $abfrage2->fetch()) {
$overdue_array[] = array("todoID" => $row["todoID"], "mitarbeiterID" => $row["mitarbeiterFID"], "mitarbeiterEmail" => $row2["email"]);
}
}
}
}
}
结果如下:
您可以通过 JOIN(如@mickmackusa 所说)强烈改进您的请求,甚至可以使用 PDO Fetch Statements(例如 PDO FETCH_GROUP 或PDO 获取关联)。您可以通过一个(更大但更好的)请求直接获得您想要的结果。
然而,如果您只想使用 PHP 对数组进行排序,使用 foreach 可以完成这项工作。
foreach ($array as $todo) {
if (!isset($newArray[$todo["mitarbeiterEmail"]])) {
// Here we create a new array with the email as a key and put the two first key-values in it with array_slice
$newArray[$todo["mitarbeiterEmail"]] = [array_slice($todo, 0, 2)];
} else {
// Here we push another todo if the email is already declared as a key
array_push($newArray[$todo["mitarbeiterEmail"]], array_slice($todo, 0, 2));
}
}
// Check your new array
print_r($newArray);
您还可以通过组合 array_multisort to sort by emails then array_reduce 删除保留关联数据的重复元素来避免 foreach。可以提出很多解决方案。
让我们用一些最佳实践来完善您的脚本...
- 仅在需要时向 SELECT 子句添加列
- 享受 PDO 非常方便的抓取模式 --
FETCH_GROUP
非常适合您的情况。
- 始终努力减少访问数据库的次数
- 始终尽量减少使用的循环次数。
推荐代码(没错,就是这么简单):
$sql = "SELECT email, todoID, mitarbeiterFID
FROM todo
JOIN mitarbeiter ON mitarbeiterID = mitarbeiterFID
WHERE archiv = 0
AND status != 3
AND durchfuehrung < CURRENT_DATE";
foreach ($db->query($sql)->fetchAll(PDO::FETCH_GROUP) as $email => $rows) {
sendSummary($email, $rows, $company, $db);
}
郑重声明,我不知道$company
来自哪里。
我想将分配给特定员工的逾期任务作为电子邮件摘要发送。多个待办事项可能分配给同一个员工。因此可以将多个待办事项分配给同一名员工并且已过期。这就是问题开始的地方...
所以我所做的是从数据库中抓取所有逾期任务,然后抓取分配给任务的员工。我创建了一个由 todoID
、employeeID
和 employeeEmail
组成的数组。现在,是否有更好的方法来执行此操作,如果没有,我如何按电子邮件地址对行进行分组?
最终结果应该是一个数组,显示分配给一名员工的每个逾期待办事项。
// Get all Todos that are not archived
$sql = "SELECT * FROM todo WHERE archiv = 0";
$abfrage = $db->prepare($sql);
$abfrage->execute();
$overdue_array = array();
// Now we get everything that's overdue from the Database
while ($row = $abfrage->fetch()) {
if ($row["status"] !== 3) {
if ($row["archiv"] !== 1) {
if ($row["durchfuehrung"]) {
if (strtotime($row["durchfuehrung"]) < strtotime(date("Y-m-d"))) {
// Here we now get the email from the assiged employee to the todo
$sql2 = "SELECT email FROM mitarbeiter WHERE mitarbeiterID = :mitarbeiterFID";
$abfrage2 = $db->prepare($sql2);
$abfrage2->bindParam("mitarbeiterFID", $row["mitarbeiterFID"]);
$abfrage2->execute();
while ($row2 = $abfrage2->fetch()) {
$overdue_array[] = array("todoID" => $row["todoID"], "mitarbeiterID" => $row["mitarbeiterFID"], "mitarbeiterEmail" => $row2["email"]);
}
}
}
}
}
结果如下:
您可以通过 JOIN(如@mickmackusa 所说)强烈改进您的请求,甚至可以使用 PDO Fetch Statements(例如 PDO FETCH_GROUP 或PDO 获取关联)。您可以通过一个(更大但更好的)请求直接获得您想要的结果。
然而,如果您只想使用 PHP 对数组进行排序,使用 foreach 可以完成这项工作。
foreach ($array as $todo) {
if (!isset($newArray[$todo["mitarbeiterEmail"]])) {
// Here we create a new array with the email as a key and put the two first key-values in it with array_slice
$newArray[$todo["mitarbeiterEmail"]] = [array_slice($todo, 0, 2)];
} else {
// Here we push another todo if the email is already declared as a key
array_push($newArray[$todo["mitarbeiterEmail"]], array_slice($todo, 0, 2));
}
}
// Check your new array
print_r($newArray);
您还可以通过组合 array_multisort to sort by emails then array_reduce 删除保留关联数据的重复元素来避免 foreach。可以提出很多解决方案。
让我们用一些最佳实践来完善您的脚本...
- 仅在需要时向 SELECT 子句添加列
- 享受 PDO 非常方便的抓取模式 --
FETCH_GROUP
非常适合您的情况。 - 始终努力减少访问数据库的次数
- 始终尽量减少使用的循环次数。
推荐代码(没错,就是这么简单):
$sql = "SELECT email, todoID, mitarbeiterFID
FROM todo
JOIN mitarbeiter ON mitarbeiterID = mitarbeiterFID
WHERE archiv = 0
AND status != 3
AND durchfuehrung < CURRENT_DATE";
foreach ($db->query($sql)->fetchAll(PDO::FETCH_GROUP) as $email => $rows) {
sendSummary($email, $rows, $company, $db);
}
郑重声明,我不知道$company
来自哪里。