Столбец PHP SQL SUM с условием

У меня есть таблица table_order, как показано ниже:

orderid | orderdate   | price  | deptnr
--------+-------------+--------+----------
1       | 2019-07-12  | 50000  | 1
2       | 2019-07-12  | 30000  | 1
3       | 2019-07-13  | 40000  | 1
4       | 2019-07-14  | 50000  | 1

Мне нужно вывести весь столбец в table_order с условием, что если есть одна и та же дата, значение price будет накапливаться в одну запись (записи в столбцах 1 и 2 должны быть объединены с общей ценой 50000+30000). Вот что я сделал:

// $sql = mysqli_query($con, "SELECT * FROM table_order
//  WHERE deptnr='$departmetnnr' AND orderstatus='CLOSE'
//  AND orderdate BETWEEN '$oneyearbefore' AND '$currentdate' ORDER BY orderdate"); 

$sql = mysqli_query($con, "
    SELECT SUM(price) AS totalprice 
      FROM table_order 
     WHERE deptnr = '$departmetnnr' 
       AND orderstatus='CLOSE' 
       AND orderdate BETWEEN '$oneyearbefore' AND '$currentdate' 
     ORDER
        BY orderdate
");

$data = array();
while($row=mysqli_fetch_assoc($sql)) {
    $data[] = ($row);
}               
$json = json_encode($data);

Честно говоря, я новичок в PHP и SQL, я пытаюсь создать простой веб-сервис для мобильных приложений, поэтому я хочу обрабатывать все вычисления на сервере и выводить в виде JSON.

Я прочитал некоторые базовые утверждения о PHP и SQL (в w3school, когда-то в ответе на переполнение стека), проблема, связанная с моей, например это, но я еще не нашел правильный вывод. Я люблю читать любые предложения / справочные ссылки, если таковые имеются. Заранее спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
0
1 429
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно GROUP BY orderdate, если вы хотите получить сумму за каждую дату. Это создает одну группу для каждого из различных значений orderdate, и затем вы можете использовать агрегатную функцию SUM(), чтобы получить каждую сумму для каждой группы (так что для вас это сумма цен для каждой даты).

Если вы не укажете GROUP BY orderdate, вы просто получите сумму по всем строкам.

SELECT SUM(price) as totalprice, orderdate
FROM table_order
WHERE deptnr='$departmetnnr' 
  AND orderstatus='CLOSE' 
  AND orderdate  BETWEEN '$oneyearbefore' AND '$currentdate' 
GROUP BY orderdate
ORDER BY orderdate

Тем не менее, в настоящее время вы вводите переменные непосредственно в запрос, чего следует избегать, используя подготовленный оператор.

$stmt = $con->prepare("SELECT SUM(price) as totalprice, orderdate
                       FROM table_order
                       WHERE deptnr=? 
                         AND orderstatus='CLOSE' 
                         AND orderdate  BETWEEN ? AND ? 
                       GROUP BY orderdate
                       ORDER BY orderdate");
$stmt->bind_param("sss", $departmetnnr, $oneyearbefore, $currentdate);
$stmt->execute();
$stmt->bind_result($totalprice, $orderdate);
while ($stmt->fetch()) {
    $data[] = ["totalprice" => $totalprice, "orderdate" => $orderdate];
}
$stmt->close();
$json = json_encode($data);

Вы также можете использовать функции SQL для создания 1 года в прошлом и получения текущей даты вместо использования значений PHP. Используйте CURDATE(), чтобы получить текущую дату, затем определите интервал в 1 год, из которого вы вычтете, они станут диапазонами для вашего BETWEEN.

$stmt = $con->prepare("SELECT SUM(price) as totalprice, orderdate
                       FROM table_order
                       WHERE deptnr=? 
                         AND orderstatus='CLOSE' 
                         AND orderdate  BETWEEN CURDATE() AND CURDATE() - INTERVAL 1 YEAR
                       GROUP BY orderdate
                       ORDER BY orderdate");
$stmt->bind_param("s", $departmetnnr);
$stmt->execute();
$stmt->bind_result($totalprice, $orderdate);
while ($stmt->fetch()) {
    $data[] = ["totalprice" => $totalprice, "orderdate" => $orderdate];
}
$stmt->close();
$json = json_encode($data);

Зачем использовать подготовку ?? кстати, ваше объяснение очень-очень ясное, но все же есть ошибка в соответствии с bind_param

MrX 15.07.2019 11:40

И что это за ошибка? И вы должны использовать всегдаprepare(), когда вам нужны переменные PHP в запросе. Всегда! Это сделано для того, чтобы в худшем случае предотвратить SQL-инъекцию, а в лучшем случае – чтобы данные не нарушили ваш запрос.

Qirel 15.07.2019 11:41

о, обычно я помещаю переменную непосредственно в оператор sql, потому что переменная имеет значение заголовка HTTP, затем я пытаюсь изменить с помощью подготовки. Ошибка Uncaught Error: Call to a member function bind_param() on bool in

MrX 15.07.2019 11:45

Не используйте переменные в запросе — используйте заполнители и используйте prepare(), особенно те, которые получены из любого пользовательского ввода. -- Я не вижу deptnr в приведенном выше определении таблицы. Это часть таблицы table_order? $stmt будет логическим значением, если запрос завершится ошибкой (что произойдет независимо от того, используете ли вы prepare() или query() — не используйте query() здесь.. ;-)

Qirel 15.07.2019 11:47

Вы можете добавить mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); перед созданием соединения new mysqli()/mysqli_connect(), чтобы получить более конкретные ошибки.

Qirel 15.07.2019 11:48

ах даа извините, deptnr является частью столбца в table_order, я отредактирую вопрос

MrX 15.07.2019 11:50

Как указано выше, добавьте строку с mysqli_report() перед подключением, и вы получите исключение с Зачем, запрос не выполнен.

Qirel 15.07.2019 11:52

Спасибо за все советы, теперь это решается с небольшими изменениями :)

MrX 16.07.2019 04:37

Вам нужно добавить GROUP BY orderdate, и все готово.

Другие вопросы по теме