Изваждане на резултати от 1 таблица по години

Ticketa

Registered
Привет
имам таблица `sales` , както и колони: id, name, sales, year, month, data

Като данните са примерни:
1, 'asd', '150.00', '2018', '1', '17-01-2018',
2, 'asd1', '160.00', '2018', '1', '18-01-2018',
3, 'asd1', '130.00', '2018', '1', '19-01-2018',
4, 'asd1', '110.00', '2018', '1', '20-01-2018',

5, 'as1d', '110.00', '2019', '1', '17-01-2019',
6, 'asdd', '10.00', '2019', '1', '17-01-2019',
7, 'asad', '190.00', '2019', '1', '17-01-2019',
8, 'adsd', '180.00', '2019', '1', '17-01-2019',

Същите данни ги извеждам, чрез обикновена заявка:
SELECT * FROM `sales` ORDER BY id DESC;

Код:
if ($result->num_rows > 0) { 
echo '<table>';
while($row = $result->fetch_assoc()) {
echo '<tr><td>'.$row['name']</td><td>'.$row['sales']</td></tr>';
}
echo '</table>';
}

Резултат към момента:
Код:
<table>
<tr>
<td>asd</td>
<td>150.00</td>
</tr>
<tr>
<td>asd1</td>
<td>160.00</td>
</tr>
<tr>
<td>asd1</td>
<td>130.00</td>
</tr>
</table>

Обаче искам, някак си да бъдат групирани по години. Т.е.
Код:
<table>
<tr><th colspan="2">2018 </th></tr>
<tr>
<td>asd</td>
<td>150.00</td>
</tr>
<tr>
<td>asd1</td>
<td>160.00</td>
</tr>
<tr><th colspan="2">2019</th></tr>
<tr>
<td>asd1</td>
<td>130.00</td>
</tr>
<tr>
<td>asd</td>
<td>150.00</td>
</tr>
<tr>
<td>asd1</td>
<td>160.00</td>
</tr>
</table>


Тоест записа, който е в определена година да се показва под годината си.
 
Най-елементарно ще бъде да сортираш по дата:

[sql]SELECT * FROM `sales` ORDER BY date DESC; [/sql]

И тогава в скрипта ще четеш резултатите на купчини с еднакви години.

Друг вариант е да дадеш групирането на базата, но тогава ще ти се смачкат (concat) резултатите за всяка година в 1 резултат:
https://stackoverflow.com/questions/149772/how-to-use-group-by-to-concatenate-strings-in-mysql
И ще трябва да разбиваш обратно конкатенирани стрингове (explode), и да циклиш върху всяко разбиване.

Третото, за което се сещам, е да си подготвиш предварително шаблон на заявка, която връща резултати по подадена година:
[sql]SELECT * FROM `sales` WHERE date = ?[/sql]
И циклиш през всички години, които можеш да вземеш с
[sql]SELECT DISTINCT YEAR(date) FROM `sales`[/sql]
Така е по-неефективно, но имаш по-добър (по-скоро по-лесен) контрол върху резултатите (напр. можеш лесно да избереш да не правиш заявка за година/и, която не искаш да показваш, или обратното).

Като за начало ти препоръчвам да започнеш с първия вариант, ако в някакъв момент стане тегаво, можеш да изпробваш другите 2.
 
Направих го по-следния начин:

Код:
<?php
$result = $mysqli->query("SELECT * FROM `turnover` GROUP BY `year` ORDER BY turnover_id DESC");
if ($result->num_rows > 0) {
    echo '<table>';
    while($row = $result->fetch_assoc()) {
        echo '<tr><th colspan="1"><h1>'.$row['year'].'</h1></th></tr>';
        $byYear = $mysqli->query("SELECT * FROM `turnover` WHERE `year`='".$row['year']."' ORDER BY turnover_id DESC");
        if ($byYear->num_rows > 0) {
            while($byYearRow = $byYear->fetch_assoc()) {
                echo "<tr><td>" . $byYearRow["data"]. "</td></tr>";
            }
        }
    }
    echo '</table>';
} else {
    echo '- няма намерени данни за избрания период -';
}
?>

Бих искал, ако някой може и му се занимава да предложи и друг вариант, така че при повече записи да бъде максимално оптимизирано. Към момента с около 400 записа, страница се зарежда за около

Page generated in 0.0726 seconds.

Не съм сигурен дали е много или малко, но може би варианта, който използвам не е най-добрия - въпреки, че върши работа?
 
Ще се повторя:

Третото, за което се сещам, е да си подготвиш предварително шаблон (mysqli_prepare()) на заявка, която връща резултати по подадена година:
[sql]SELECT * FROM `sales` WHERE date = ?[/sql]
И циклиш през всички години, които можеш да вземеш с
[sql]SELECT DISTINCT YEAR(date) FROM `sales`[/sql]
Така е по-неефективно, но имаш по-добър (по-скоро по-лесен) контрол върху резултатите (напр. можеш лесно да избереш да не правиш заявка за година/и, която не искаш да показваш, или обратното).

Изпуснал си частта с prepare-ването. В момента на всяка итерация правиш нова заявка, която пращаш до базата и влечеш резултати. Ако не знаеш как става - прочети за mysqli_prepare.
Идеята е, че пращаш шаблона на заявката веднъж, и след това само подаваш година, за да вземеш резултатите.

И за да вземеш годините по-добре използвай заявката, която ти показах - с твоя начин караш базата да обработва всичко и да групира редовете; с distinct взимаш само интересуващата те колона и базата маха дубликатите.
 

Горе