在 PHP 中,有没有办法循环查询并根据值将其组织到特定列中?

Posted

技术标签:

【中文标题】在 PHP 中,有没有办法循环查询并根据值将其组织到特定列中?【英文标题】:In PHP, is there a way to loop through a query and organize it into a specific column based on a value? 【发布时间】:2019-08-24 08:31:00 【问题描述】:

我正在使用 Laravel 并尝试从查询中填充 html 表。数据库中的表包含idusershift 等列。大约有 100 个条目,shift 列将包含字母 ABCD。我想将它输出到单个 HTML 表中,以便在循环时,输出表中的第一列将只包含具有该值的 A 的条目,第二个 B 的条目,依此类推。

这是我的查询:

Shift::orderBy('shift', 'ASC')
        ->get();

这当然会按字母顺序排序,然后当我循环使用它时:

      ...
  <tbody>
    @foreach ($shifts as $shift)
          <tr>
              <td> $shift->id </td>
            ...
           </tr>
      @endforeach
   </tbody>
  ...

或类似的变体,我已经尝试了很多,它将遍历所有带有A 的条目并在表格中创建这些单元格/行,然后从B 开始。但是到那时,因为已经创建了这些,B 条目开始了,但是许多 A 条目已经关闭。

我已经遍历它并创建了四个单独的表,但我更愿意将它合二为一。我想用 Laravel Excel 导出表格,如果它们是单独的表格,它只是将它们堆叠起来,但我希望它们并排。无论如何,这就是我的意思和想要的(带有字母的行将是决赛表中的其他信息):

我错过了什么?我觉得我做的事情不是很简单。谢谢你的帮助。

【问题讨论】:

您可能需要重新评估您存储和检索数据的方式。但是如果你必须实现这个目标,听起来你需要将它们分成 4 个数组,然后将它们重新组合在一起,每个数组值包含一个嵌套数组,其中包含 A-D 的潜在值。 是的,我想我必须改变一些东西。我宁愿不这样做,因为这只是为了在将其导出到电子表格并循环创建 4 个表时显示得更好。但这是另一个话题。 【参考方案1】:

是的,您可以使用为此目的而存在的usort 对它们进行排序。 usort() 将使用用户定义的比较函数按值对数组进行排序。

$arr = [
    ['letter'=>'C'],
    ['letter'=>'A'],
    ['letter'=>'B'],
    ['letter'=>'A'],
    ['letter'=>'D'],
];

// Function to sort by provided column name
function cmp($key)
    // Returns comparision function to be used with usort
    return function($a,$b)use($key)
        return strcmp($a[$key], $b[$key]);
    ;

usort($arr, cmp('letter'));
print_r($arr);

希望对你有帮助,

【讨论】:

【参考方案2】:

我想说实现这一点的最有效方法是在数据库级别进行排序。为此,您应该使用 orderBy() 方法。同样好的方法是有这个范围。

public function scopeOrderByShiftsAsc($query)

    return $query->orderBy('shifts', 'asc')->orderBy('created_at', 'desc');


// then in your controller
public function index()

    $users = \App\User::orderByShiftsAsc()->get();

您可以在 Query builder 或 eloquent 的方法链中使用这种方式 (orderBy())。 Query Scopes.

【讨论】:

如果我只是分组移位(字母 AD),它只从每个字母返回一个条目。如果我进一步分组,它只会输出与原始查询相同的结果;首先是所有的As,然后是Bs,Cs,然后是Ds。我做错了吗? 现在尝试使用排序而不是分组。 这就是我的原始查询(减去范围),我想我应该发布的。它只是按字母顺序排列,所以每个字母一个接一个大约有 20 个。它们都是从电子表格中导入的,因此创建时间是相同的。我认为通过排序实现这一目标的唯一方法是通过对ABCD 的块进行分组来对其进行排序;就像从每个字母中提取第一个条目,然后为每个字母重复该条目。但我想这必须在数据库级别之后使用数组来完成。 对不起,我很困惑。您正在混合 HTML 中的表格和 DB 中的表格。您可以发布表格结构和硬编码或想要的 HTML 图像吗?您无需使用真实数据,而是帮助我们更好地了解您的要求。按照these 的建议去做。 更新了原帖。抱歉我的含糊不清和混乱。【参考方案3】:

使用:

Shift::get()->keyBy('shift')->toArray();

你得到一个类似于以下的结构:

$data = [
  "A" = [
    ['id' => 1, 'shift' => 'A'],
    ...
  ],
  "B" = [
    ['id' => 2, 'shift' => 'B'],
    ...
  ],
  ...
]

接下来,您可以遍历最大的字母并创建所需的输出结构:

$letters = array_keys($data)
$maxLength = 0
foreach($letters as $letter) 
  $len = count($data[$letter]);
  if ($len > $maxLength) $maxLength = $len;

$output = []
for($i = 0; $i < $maxLength: $i++) 
   $newRow = [];
   foreach($letters as $letter) 
     if (isset($data[$letter][$i])) 
       $newRow[$letter] = $data[$letter][$i]['id'];
      else 
       $newRow[$letter] = '';
     
   
   $output[] = $newRow;

然后您可以将输出传递给刀片文件并将表创建为:

@foreach ($output as $row)
      <tr>
          <td> $row['A'] </td>
          <td> $row['B'] </td>
          ...
       </tr>
  @endforeach

【讨论】:

谢谢,但该查询不是只导致该数组中有四个条目(每个字母 1,因为这是关键)?我需要收集然后循环遍历的每个字母大约有 25 行。 不,这应该得到一切。

以上是关于在 PHP 中,有没有办法循环查询并根据值将其组织到特定列中?的主要内容,如果未能解决你的问题,请参考以下文章

java根据HashMap中的值将其元素排序

根据 NSDictionary 键值将 NSArray 拆分为子数组

根据列值将 SQL 结果组合成组

循环遍历Vue.js中的动态数组,然后根据对应的值将每个对象组件添加到单独组件中的div中?

将值传递给派生表

有没有办法在纯 PHP 中检测循环数组?