我有一个关于我的代码的问题,这是我的代码连接到数据库,选择一些唯一的数据和求和这些唯一的数据从另一个表,我的代码没有问题,这一切都好,但它需要很长时间的查询。
<?php
include "koneksi.php";
$no=1;
$arqury=odbc_exec($koneksi, "SELECT DISTINCT NIP_AR,NAMA_AR FROM USRBPS.MASTERFILE");
while($ar=odbc_fetch_array($arqury)){
$total=0;
$ambilqury=odbc_exec($koneksi, "SELECT NPWP FROM USRBPS.MASTERFILE WHERE NIP_AR='$ar[NIP_AR]'");
while($ambil=odbc_fetch_array($ambilqury)){
$testqury=mysql_query("SELECT SUM(jumlah_bayar) as PENERIMAAN FROM mpnruteng WHERE npwp='$ambil[NPWP]'");
$test=mysql_fetch_array($testqury);
$total += $test[PENERIMAAN];
}
if($ar[NIP_AR]==""){
echo "<tr><td>$no</td><td colspan=2>UNASSIGN</td><td>$total</td>";
}
else{
echo "<tr><td>$no</td><td>$ar[NAMA_AR]</td><td>$ar[NIP_AR]</td><td>$total</td></tr>";
}
$no++;
}
?>
on就是这样,
|Name |num_se
---------------
|andre |1111
|john |2222
|simon |3333
|andre |4444
|andre |5555
|simon |6666
|john |7777
|num_se |Total
---------------
|1111 |12
|2222 |15
|3333 |10
|4444 |8
|5555 |20
|6666 |18
|7777 |22
所以,我需要的是得到'Total'的总和,从每个'Name'。我想获得的是名称"unique"的列表(在本例中是Andre, John和Simon),以及从num_se获得的每个"Total"的总和。
对不起,我的英语不好,但我希望你能理解。
解释一下您是在预先处理两个独立的数据源。
它很慢,因为你试图在PHP中循环你的结果集,调用单个查询从另一个表返回单行,这是非常低效的。
让数据库通过使用JOIN
来处理两个相关表之间的关系,然后让它处理您的总总数,而不仅仅是单个总数。
下面的查询将获得nip_ar和nama_ar的每一对不同的总和:
SELECT
t1.NIP_AR,
t1.NAMA_AR,
SUM(t2.jumlah_bayar) as PENERIMAAN
FROM
USRBPS.MASTERFILE t1
INNER JOIN mpnruteng t2
ON t2.npwp = t1.npwp
GROUP BY
1, 2
但是无论如何,你要把它卷成一个大的$total
,所以这将为你得到它:
SELECT
SUM(PENERIMAAN) as PENERIMAAN
FROM
(
SELECT
t1.NIP_AR,
t1.NAMA_AR,
SUM(t2.jumlah_bayar) as PENERIMAAN
FROM
USRBPS.MASTERFILE t1
INNER JOIN mpnruteng t2
ON t2.npwp = t1.npwp
GROUP BY
1, 2
)
你可以配置一个从oracle服务器到mySql服务器的链接。参考使用异构服务代理-第4章。设置对非oracle系统的访问。我的理解是你不能从mySql链接到Oracle。
这将允许您在您的Oracle实例上运行上述查询。尽管您需要更新表名以使其完全符合数据源名称
如果我理解正确,这个查询可能有帮助
SELECT t1.Name, sum(t2.Total)
FROM (table1 t1 LEFT JOIN table2 t2 ON t1.num_se = t2.num_se)
GROUP BY t1.Name
根据大小写修改表名和列名。
我不知道你为什么使用两个分开的数据源。但是,我认为这种方法可以提高代码的效率。
首先,通过以下查询获得属于每个name
的所有num_se
的列表:
"SELECT Name, GROUP_CONCAT(num_se) as nums FROM table1 GROUP BY Name"
现在你的结果数组('$ar')将有一个元素"1111,2222"
,键为nums
其次,使用此查询获取每个name
"SELECT SUM(Total) as total FROM Table2 WHERE num_se IN (" . $ar['nums'] . ")"
您将获得每个name
的total
,而不需要第二个循环。
请记住使用转义技术来确保您的查询是安全的
如果你在Windows上,我注意到使用localhost而不是127.0.0.1会减慢到数据库的连接。
在给出任何解决方案之前,我想分享一下您的查询太慢的原因。如果您仔细查看您的代码,您正在打开数据库连接,以便在第一个查询结果中达到记录。主要的开销是针对数据库打开和运行查询。所以想象一下,如果你在第一个结果中有1000条记录,你将打开数据库连接1000次,这将使它非常非常慢。使用Trung规定的内连接或子查询。如果不可能的话,使用存储过程并将逻辑放在SP中也可以帮助您获得性能。创建一个存储过程,并将输入参数作为从另一个数据库获得的以逗号分隔的id传递,在SP中使用逗号分隔的id来循环和执行选择语句。您可以使用临时表来实现这一点。这样做的好处是您只需要打开数据库连接一次。