MySQL 中使用 PHP 的多维数组和聚合函数?
Posted
技术标签:
【中文标题】MySQL 中使用 PHP 的多维数组和聚合函数?【英文标题】:Multidimensional array and aggregate functions in MySQL using PHP? 【发布时间】:2016-12-06 14:05:43 【问题描述】:更新
如何在名为 CUMULATIVE TOTAL 的 u2 旁边再显示 1 列 它应该根据辅导员显示学生总数、应付总额和应付总额。
假设我有 c1,c2,c3,c4 作为辅导员,u1,u2 作为大学 假设 c1 在每所大学有 5 名学生,在这种情况下,CUMULATIVE TOTAL 列应显示学生总数列为 [c1][No of students]=10, [c1][Payable]=some value, [c1][Paid]=一些价值,[c1][平衡]=一些价值
请检查以下代码,让我知道是否有任何方法可以在 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>
【问题讨论】:
哪个驱动不工作?错误信息是什么? 没关系,如果你能帮我解决我的问题 这不是我问题的答案?? 以前我遇到致命错误:在第 165 行错误 上调用 /home/demosar30/public_html/admission/test3.php 中未定义的方法 mysqli_result::fetch_all() 错误 但我重新写我的代码现在可以正常工作了 顺便说一句。我不会在 mysql 中解决这个问题,而是在 PHP 端使用 array_chunk 与 array_sum 结合。这可以在 mysql 中完成,但在那里效率应该很低。 【参考方案1】:我希望这是您正在关注的代码:
<?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`)
【讨论】:
对您的答案投赞成票,实际上我的数据库中的 total_payable 列中有一些值,我需要获取不同的 total_payable 的总和,并且应该按 customer_id 分组。请将其添加到您的代码中,除了您的代码工作正常。这样我就可以将我的赏金奖励给你,我会将你的答案标记为正确。 当然,我会的。您能否将您拥有的表格中的数据样本发送给我并在您的问题中更新它?如果我是正确的,您在 wll_customer 表中有多个相同的 customer_id 输入,结果您得到重复? 我的意思是一些表的示例模式,以便我可以相应地更新我的查询。 我更新的图片是输出格式,在 wll_customer 表中我有 customer_id(主键)、customer_university、customer_counsellor,在 wll_invoice 表中我有 customer_id(外键指 wll_customer 表),应付,支付和到期。 好的,所以您在发票表中没有像主键这样的独特键【参考方案2】:您的 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
【讨论】:
在 GROUP BY customer_counselor, customer_counselor 之后我得到了相同的答案 不,您可能收到了缓存响应或更改了错误的脚本。 是的,现在它正在工作,我想在最后根据辅导员获得所有大学的综合总数,我该怎么做才能分享代码 为了清楚起见,我想在 u2 旁边显示另外 1 个名为 total 的列,它应该显示学生总数,以此类推 这是一个新问题。以上是关于MySQL 中使用 PHP 的多维数组和聚合函数?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 php mysql 查询中为 jQuery 自动完成准备多维数组?