Несколько сумм запросов с одним запросом - PullRequest
0 голосов
/ 02 ноября 2018

Я хотел бы создать коллекцию в соответствии с некоторыми полями в информации о продукте и таблице истории продуктов в таблице продуктов. Как это сделать в одном запросе?

мой пример кода:

    <table> 
    <thead> 
        <tr> 
            <th>Product</th>
            <th>Model</th>
            <th>Actıve Total</th>
            <th>Pasıve Total</th>
            <th>Color Total</th>
        </tr> 
    </thead> 
    <tbody> 
<?php 

$product = $db->get_results("SELECT * FROM product WHERE (status='ACTIVE')");


foreach ($product as $p ){

$active_total   = $db->get_var("SELECT SUM(price) FROM product_history WHERE pid='$p->pid' AND status='AKTIVE'");
$pasive_total   = $db->get_var("SELECT SUM(price) FROM product_history WHERE pid='$p->pid' AND status='PASIVE'");
$color_total    = $db->get_var("SELECT SUM(price) FROM product_history WHERE pid='$p->pid' AND status='ACTIVE' AND color='BLUE'");
?>      
        <tr> 
            <td><?php echo $p->name; ?></td>
            <td><?php echo $p->model; ?></td> 
            <td><?php echo $active_total; ?></td> 
            <td><?php echo $pasive_total; ?></td> 
            <td><?php echo $color_total; ?></td>
         </tr> 
<?php } ?>
    </tbody> 
</table>

enter image description here

enter image description here

Спасибо.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Полагаю, вы хотите знать все цвета, а не только синий? В этом случае я бы пошел с LEFT JOIN

SELECT p.pid, p.name, SUM(ph.price) AS total, ph.color, ph.status 
FROM product p
LEFT JOIN product_history ph ON (p.pid = ph.pid)
WHERE p.status = 'ACTIVE'
GROUP BY p.pid, p.name, ph.status, ph.color

FYI: Вы действительно должны использовать подготовленные операторы для обработки изменения контекста и предотвращения любых проблем и уязвимостей.

0 голосов
/ 02 ноября 2018

Вы можете использовать условное агрегирование, чтобы получить эти результаты из одного запроса:

$sql = "SELECT
            SUM(CASE WHEN status='AKTIVE' THEN price ELSE 0 END) AS aktive,
            SUM(CASE WHEN status='PASIVE' THEN price ELSE 0 END) AS pasive,
            SUM(CASE WHEN status='AKTIVE' AND color='BLUE' THEN price ELSE 0 END) AS color,
        FROM product_history 
        WHERE pid='$p->pid'");

Вы можете объединить оба ваших запроса в 1, используя LEFT JOIN:

$sql = "SELECT p.*,
               SUM(CASE WHEN h.status='AKTIVE' THEN h.price ELSE 0 END) AS aktive,
               SUM(CASE WHEN h.status='PASIVE' THEN h.price ELSE 0 END) AS pasive,
               SUM(CASE WHEN h.status='AKTIVE' AND h.color='BLUE' THEN h.price ELSE 0) AS color
        FROM product p
        LEFT JOIN product_history h ON h.pid = p.pid
        WHERE p.status='ACTIVE'
        GROUP BY p.pid";

Если единственное интересующее значение из product - это pid (в целях сопоставления со значением pid в product_history), вы должны изменить p.* в запросе на p.pid. В противном случае вы должны в идеале перечислить конкретные поля, значения которых вы хотите. См. Почему SELECT * считается вредным?

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