动态将行转置为列

Dynamically Transpose Row into Column

我正在尝试让查询结果在第一列显示 sku 以及随后的不同月份的其余部分以及特定月份下每个月份的数量。

SELECT DATE_FORMAT(date_defect,'%Y-%m') AS date, sku AS 'sku', COUNT(sku) AS 'COUNT' 
FROM defect 
WHERE date_defect 
BETWEEN '".$report->sDate."' AND '".$report->fDate."' 
GROUP BY date,sku 

我希望能够选择日期范围,这就是我将这些对象作为日期条件的原因。 table 目前的样子

DATE SKU COUNT
MONTH1 SKU-1 COUNT1
MONTH1 SKU-2 COUNT2
MONTH2 SKU-1 COUNT1
MONTH2 SKU-2 COUNT2

这就是我希望 table 的样子

SKU MONTH1 MONTH2 MONTH3
SKU-1 COUNT1 COUNT2 COUNT3
SKU-2 COUNT1 COUNT2 COUNT3

而不是 post 您的数据的屏幕截图,将其包含在您的问题中。你让别人很难帮助你。

鉴于此减少的样本数据:

$data = array(
  array('date' => '2022-01', 'sku' => 'C1S', 'COUNT' => 1),
  array('date' => '2022-01', 'sku' => 'F8M', 'COUNT' => 3),

  array('date' => '2022-02', 'sku' => 'F8M', 'COUNT' => 4),
  array('date' => '2022-02', 'sku' => 'K1M', 'COUNT' => 6),


  array('date' => '2022-03', 'sku' => 'F8M', 'COUNT' => 3),
  array('date' => '2022-03', 'sku' => 'K1M', 'COUNT' => 10),
);

您想:

  1. 迭代数组中的每个条目。
  2. 数组中的每个项目都应根据 SKU 放入其自己的组中。
  3. 在这些组中,您想按日期轻松查找数据。
  4. 要制作列,您需要知道要显示的每个日期。

您可以为第 4 步创建一个静态的月份列表。此示例根据输入生成已用日期列表。

$grouped = array(
  // Will look like this:
  // array(
  //   "F8M" => array(
  //     "2022-01" => ...
  //   ), 
  //   ...
  // );
);
$all_dates = array();
foreach($data as $current) {
  // Assume $current == array('data' => '2022-01', 'sku' => 'F8M', ...)

  // If $grouped['F8M'] doesn't exist yet, set it to an empty array.
  if(!isset($grouped[$current['sku']])) {
      $grouped[$current['sku']] = array(); 
  }

  // You could also set it to $current['COUNT'],
  // but this way, if you add more columns later, you have the entire 
  // database row.
  $grouped[$current['sku']][$current['date']] = $current; 

  // You need the dates to make the columns later.
  $all_dates[] = $current['date'];
}

// Remove duplicates.
$all_dates = array_unique($all_dates);
// sort($all_dates); should not be needed here in this case.

然后迭代使你的 table:

echo "
<table>
  <thead>
    <tr>
      <th>SKU</th>
";
// Create a column for every date.
foreach($all_dates as $date) {
  echo "      <th>$date</th>\n";
}
echo "
    </tr>
  </thead>
  <tbody>
";

// Then show every item.
foreach($grouped as $sku => $sku_dates) {
  echo "
    <tr>
      <th>$sku</th>
";

  // Not all SKUs have data for every month, so we iterate
  // over the header columns again.
  foreach($all_dates as $date) {
    if (empty($sku_dates[$date])) {
      // Example: $data['C1S']['2022-02'] is empty(),
      // so this column is blank.
      echo "      <td> - </td>\n";
    } else {
      // Example: $data['F8M']['2022-02']['COUNT'] exists
      // and this column contains 4.
      echo "      <td>{$sku_dates[$date]['COUNT']}</td>\n";
    }
  }
  echo "
    </tr>
";
}

echo "
  </tbody>
</table>
";

如果你把问题分解成我提到的步骤,解决方案应该很容易理解,你甚至可能不需要上面列出的例子。