使用PHP的MySQL中的多维数组和聚合函数?

时间:2016-08-01 13:07:25

标签: php arrays multidimensional-array mysqli aggregate

已更新

如何在u2旁边再显示一个名为CUMULATIVE TOTAL的列 它应根据辅导员显示学生总应付总额和应付总数。

考虑我有c1,c2,c3,c4作为辅导员,u1,u2作为大学 说c1在每个大学有5个学生,那个案例CUMULATIVE TOTAL列应该显示学生总数列为[c1] [学生人数] = 10,[c1] [应付款] =某个值,[c1] [付费] =一些值,[c1] [Balence] =某个值

enter image description here


请检查以下代码,让我知道有没有办法在SUM聚合函数或任何替代解决方案中编写选择查询,因为我希望wll_invoice.total_payable应按customer_id分组。

        <?php
define('DB_MAIN', 'localhost|user|passowd|database');

class my_db{

    private static $databases;
    private $connection;

    public function __construct($connDetails){
        if(!is_object(self::$databases[$connDetails])){
            list($host, $user, $pass, $dbname) = explode('|', $connDetails);
            $dsn = "mysql:host=$host;dbname=$dbname";
            self::$databases[$connDetails] = new PDO($dsn, $user, $pass);
        }
        $this->connection = self::$databases[$connDetails];
    }

    public function fetchAll($sql){
        $args = func_get_args();
        array_shift($args);
        $statement = $this->connection->prepare($sql);
        $statement->execute($args);
         return $statement->fetchAll(PDO::FETCH_OBJ);
    }
}

$db = new my_db(DB_MAIN);
$universities = $db->fetchAll('SELECT distinct customer_university FROM wll_customer');
$counselors = $db->fetchAll('SELECT distinct customer_counselor FROM wll_customer');
$payments_ = $db->fetchAll('SELECT
    customer_counselor,
    customer_university,
    COUNT(DISTINCT customer_name) AS \'no of students\',
    SUM(DISTINCT wll_invoice.total_payable) AS payable,**//I want to make total_payable should GROUP BY customer_id** 
    SUM(wll_invoice.total_pay) AS paid,
    SUM(wll_invoice.due) AS balance
FROM
    wll_customer
        LEFT JOIN
    wll_invoice ON wll_invoice.customer_id = wll_customer.customer_id
GROUP BY customer_counselor,customer_university;');

$payments = [];
foreach ($payments_ as $payment)
$payments[$payment->customer_counselor][$payment->customer_university] = $payment;
?>

<table id="table_id" class='display table-bordered'>
    <thead>
    <tr>
        <td rowspan="2">Sl</td>
        <td rowspan="2" >counselor</td>
<?php
    foreach ($universities as $key => $university){ ?>

        <td colspan="4" ><?=$university->customer_university ?> </td>
    <?php } ?>
    </tr>
    <tr>
    <?php foreach ( $universities as $university){?>
        <td>no of students</td>
        <td>payable</td>
        <td>paid</td>
        <td>balance</td>
    <?php } ?>
    </tr>
    </thead>
    <tbody>
    <tr>
    <?php foreach ( $counselors as $counselor){?>
    <?php foreach ( $universities as $key => $university){
     $payment = $payments[$counselor->customer_counselor][$university->customer_university];
    ?>  <?php if(!$key){?>
         <td></td>
         <td><?=$counselor->customer_counselor?></td>
        <?php } ?>
        <td><?=(int)$payment->{'no of students'}?></td>
        <td><?=number_format($payment->payable,0,',','')?></td>
        <td><?=number_format($payment->paid,0,',','')?></td>
        <td><?=number_format($payment->balance,0,',','')?></td>
    <?php } ?>
    </tr>
    <?php } ?>
    </tbody>
</table>

2 个答案:

答案 0 :(得分:4)

您的SQL应按customer_university和customer_counselor进行分组:

SELECT 
customer_counselor, 
customer_university, 
COUNT(customer_name) AS \'no of students\', 
SUM(wll_invoice.total_payable) AS payable, 
SUM(wll_invoice.total_pay) AS paid, 
SUM(wll_invoice.due) AS balance 
FROM wll_customer 
LEFT JOIN wll_invoice 
 ON wll_invoice.customer_id = wll_customer.customer_id 
GROUP BY customer_counselor, customer_university

答案 1 :(得分:2)

我希望这是您正在寻找的代码:

<?php
define('DB_MAIN', 'localhost|user|password|database');

class my_db{

    private static $databases;
    private $connection;

    public function __construct($connDetails){
        if(!is_object(self::$databases[$connDetails])){
            list($host, $user, $pass, $dbname) = explode('|', $connDetails);
            $dsn = "mysql:host=$host;dbname=$dbname";
            self::$databases[$connDetails] = new PDO($dsn, $user, $pass);
        }
        $this->connection = self::$databases[$connDetails];
    }

    public function fetchAll($sql){
        $args = func_get_args();
        array_shift($args);
        $statement = $this->connection->prepare($sql);
        $statement->execute($args);
         return $statement->fetchAll(PDO::FETCH_OBJ);
    }
}

$db = new my_db(DB_MAIN);
$universities = $db->fetchAll('SELECT distinct customer_university FROM wll_customer order by customer_university');
/**
 * Adding Cummulative university 
 */
$cumulativeUniversity = new StdClass();
$cumulativeUniversity->customer_university = "CUMULATIVE TOTAL";
$universities[] = $cumulativeUniversity;

$counselors = $db->fetchAll('SELECT distinct customer_counselor FROM wll_customer order by customer_counselor');
$payments_ = $db->fetchAll('(SELECT 
    customer_counselor, 
    customer_university, 
    COUNT(distinct wll_invoice.customer_id) AS \'no of students\', 
    SUM(wll_invoice.total_payable) AS payable, 
    SUM(wll_invoice.total_pay) AS paid, 
    SUM(wll_invoice.due) AS balance 
    FROM wll_customer 
    LEFT JOIN wll_invoice 
     ON wll_invoice.customer_id = wll_customer.customer_id 
    GROUP BY customer_counselor, customer_university
    order by `customer_counselor`, `customer_name`)
UNION
    (SELECT 
    customer_counselor, 
    "CUMULATIVE TOTAL" as university, 
    COUNT(distinct wll_invoice.customer_id) AS \'no of students\', 
    SUM(wll_invoice.total_payable) AS payable, 
    SUM(wll_invoice.total_pay) AS paid, 
    SUM(wll_invoice.due) AS balance 
    FROM wll_customer 
    LEFT JOIN wll_invoice 
     ON wll_invoice.customer_id = wll_customer.customer_id 
    GROUP BY customer_counselor
    ORDER BY `customer_counselor`)');

$payments = [];
foreach ($payments_ as $payment)
$payments[$payment->customer_counselor][$payment->customer_university] = $payment;
?>

<table id="table_id" class='display table-bordered' border="1">
    <thead>
    <tr>
        <td rowspan="2" >Counselor</td>
    <?php
    foreach ($universities as $key => $university): ?>
        <td colspan="4" ><?=$university->customer_university ?> </td>
    <?php endforeach ?>
    </tr>
    <tr>
    <?php foreach ( $universities as $university): ?>
        <td>no of students</td>
        <td>payable</td>
        <td>paid</td>
        <td>balance</td>
    <?php endforeach ?>
    </tr>
    <?php foreach ( $counselors as $counselor):?>
        <tr>
            <td>
                <?php echo $counselor->customer_counselor;?>
            </td>
        <?php foreach ( $universities as $key => $university): 
            $payment = isset($payments[$counselor->customer_counselor][$university->customer_university]) ? $payments[$counselor->customer_counselor][$university->customer_university] : null;
            if($payment):?>
                <td><?=(int)$payment->{'no of students'}?></td>
                <td><?=number_format($payment->payable,0,',','')?></td>
                <td><?=number_format($payment->paid,0,',','')?></td>
                <td><?=number_format($payment->balance,0,',','')?></td>
            <?php else:?>
                <td colspan="4"></td>
            <?php endif?>
        <?php endforeach; ?>
        </tr>
    <?php endforeach; ?>
    </thead>
</table>

我使用了以下查询,我正在使用Union来辅助员追加您正在寻找的整体数据。此外,如果您在代码中注意到,我已将累积的大学对象附加到大学列表中以处理相同的循环。

(SELECT 
customer_counselor, 
customer_university, 
COUNT(DISTINCT wll_invoice.customer_id) AS 'no of students', 
SUM(wll_invoice.total_payable) AS payable, 
SUM(wll_invoice.total_pay) AS paid, 
SUM(wll_invoice.due) AS balance 
FROM wll_customer 
LEFT JOIN wll_invoice 
 ON wll_invoice.customer_id = wll_customer.customer_id 
GROUP BY customer_counselor, customer_university
ORDER BY `customer_counselor`, `customer_name`)

UNION

(SELECT 
customer_counselor, 
"CUMULATIVE TOTAL" AS university, 
COUNT(DISTINCT wll_invoice.customer_id) AS 'no of students', 
SUM(wll_invoice.total_payable) AS payable, 
SUM(wll_invoice.total_pay) AS paid, 
SUM(wll_invoice.due) AS balance 
FROM wll_customer 
LEFT JOIN wll_invoice 
 ON wll_invoice.customer_id = wll_customer.customer_id 
GROUP BY customer_counselor
ORDER BY `customer_counselor`)

尝试将此查询用于其他值,但您确实需要更新架构。这只是一个临时解决方案:

(SELECT 
customer_counselor, 
customer_university, 
COUNT(DISTINCT wll_invoice.customer_id) AS 'no of students', 
SUM(wll_invoice.total_payable) AS payable, 
SUM(final_pay) AS paid, 
SUM(wll_invoice.total_payable - final_pay) AS balance 
FROM wll_customer 

LEFT JOIN (SELECT MAX(id) max_id, customer_id, SUM(total_pay) final_pay FROM `wll_invoice`
GROUP BY customer_id, `total_payable`) AS wll_unique ON wll_unique.customer_id = wll_customer.`customer_id`

LEFT JOIN wll_invoice 
 ON wll_invoice.customer_id = wll_unique.customer_id AND `wll_invoice`.id = wll_unique.max_id
GROUP BY customer_counselor, customer_university
ORDER BY `customer_counselor`, `customer_name`)
UNION
(SELECT 
customer_counselor, 
"CUMULATIVE TOTAL" AS university, 
COUNT(DISTINCT wll_invoice.customer_id) AS 'no of students', 
SUM(wll_invoice.total_payable) AS payable, 
SUM(final_pay) AS paid, 
SUM(wll_invoice.total_payable - final_pay) AS balance 
FROM wll_customer 

LEFT JOIN (SELECT MAX(id) max_id, customer_id, SUM(total_pay) final_pay FROM `wll_invoice`
GROUP BY customer_id, `total_payable`) AS wll_unique ON wll_unique.customer_id = wll_customer.`customer_id`

LEFT JOIN wll_invoice 
 ON wll_invoice.customer_id = wll_unique.customer_id  AND `wll_invoice`.id = wll_unique.max_id
GROUP BY customer_counselor
ORDER BY `customer_counselor`)