Второй способ сделать это. Не тестировался (возможно, некоторые опечатки), но выполнял некоторый SQL, чтобы получить данные, а затем зацикливать детали, подталкивая их к объекту, чтобы вывести строки. Это позволит справиться с тем, где компания не имеет данных за год.
Обратите внимание, что вы могли бы значительно упростить SQL, если бы у вас была таблица, в которой вы заинтересованы, и таблицу компаний.
<?php
$sql = "SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Revenue, 0) AS aValue, 'Revenue' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
UNION
SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Cost, 0) AS aValue, 'Cost' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
UNION
SELECT Sub1.Year, Sub2.Company, IFNULL(SomeTable.Profit, 0) AS aValue, 'Profit' AS Item
FROM
(
SELECT DISTINCT Year FROM SomeTable
) Sub1
CROSS JOIN
(
SELECT DISTINCT Company FROM SomeTable
) Sub2
LEFT OUTER JOIN SomeTable
ON Sub1.Year = SomeTable.Year
AND Sub2.Company = SomeTable.Company
ORDER BY Company, FIELD(Item, 'Revenue', 'Cost', 'Profit'), Year";
$query = $db->query($sql) or die($db->error()) ;
if ($row = $this->db->fetchAssoc())
{
echo "<table>";
$PrevCompany = $row['Company'];
$PrevItem = $row['Item'];
$aLine = new ProcessLine($PrevCompany, $PrevItem, true);
do
{
if ($PrevCompany != $row['Company'] or $PrevItem != $row['Item'])
{
unset($aLine);
$PrevCompany = $row['Company'];
$PrevItem = $row['Item'];
$aLine = new ProcessLine($PrevCompany, $PrevItem);
}
$aLine->Assign_Detail($row['Year'], $row['aValue'])
} while($row = $this->db->fetchAssoc());
unset($aLine);
echo "</table>";
}
class ProcessLine
{
private $Company;
private $Item;
private $row_details = array();
private $FirstRow = false
public __CONSTRUCT($Company, $Item, $FirstRow=false)
{
$this->Company = $Company;
$this->Item = $Item;
}
public __DESTRUCT()
{
if ($this->Firstrow)
{
echo "<tr><th>".$this->Company."</th><th>".$this->Item."</th>";
foreach($row_details AS $row_year=>$row_value)
{
echo "<th>$row_year</th>";
}
echo "</tr>";
}
echo "<tr><td>".$this->Company."</td><td>".$this->Item."</td><td>".implode("</td><td>", $row_details)."</td></tr>";
}
public Assign_Detail($in_year, $in_value)
{
$row_details[$in_year] = $in_value;
}
}
?>
что делать, если это доход, стоимость и прибыль имеют более 10 рядов для компании? –
Это очень вероятно .. будет иметь 20 строк за компанию. Другие предметы будут накладными расходами, маркетингом и т. Д. Thx – user3114015
Как насчет изменения структуры таблиц, а не одного отношения «один ко многим»? –